Merge lp:~tealeg/landscape-client/ui-storage into lp:~landscape/landscape-client/trunk

Proposed by Geoff Teale
Status: Merged
Approved by: Alberto Donato
Approved revision: 482
Merged at revision: 467
Proposed branch: lp:~tealeg/landscape-client/ui-storage
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 1891 lines (+1196/-327)
12 files modified
glib-2.0/schemas/com.canonical.landscape-client-settings.gschema.xml (+37/-0)
landscape/ui/controller/configuration.py (+11/-35)
landscape/ui/controller/tests/test_configuration.py (+5/-5)
landscape/ui/lib/polkit.py (+3/-2)
landscape/ui/model/configuration/mechanism.py (+2/-1)
landscape/ui/model/configuration/proxy.py (+5/-2)
landscape/ui/model/configuration/state.py (+329/-144)
landscape/ui/model/configuration/tests/test_state.py (+458/-137)
landscape/ui/model/configuration/tests/test_uisettings.py (+189/-0)
landscape/ui/model/configuration/uisettings.py (+57/-0)
landscape/ui/tests/helpers.py (+95/-0)
setupui.py (+5/-1)
To merge this branch: bzr merge lp:~tealeg/landscape-client/ui-storage
Reviewer Review Type Date Requested Status
Alberto Donato (community) Approve
Free Ekanayaka (community) Approve
Review via email: mp+94393@code.launchpad.net

Description of the change

The second part of the fix for bug #931937,

This branch does the following:

 1. Removes the TestedGoodState and TestedBadState to reflect the decision not to tackne testing of configurations in this phase.
 2. Performs 3 stages of data setup:
     i. use code level defaults in the VirginState
     ii. overwrite user visible values with current values in GSettings (VirginState -> Initialised)
     iii. overwrite either hosted or local values from the configuration file values (VirginState -> Initialised)
 3. Persist data in two places:
     i. write all user visible data back to GSettings.
     ii. write either hosted or local values to the configuration file.

To post a comment you must log in.
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Great stuff, +1!

[1]

+class UISettings(object):

Please add a class docstring here.

[2]

+ def get(self, *args):

and

+ def set(self, *args):

Please add method docstrings explaining what these methods do in detail, as they seem to have non trivial logic.

[3]

+ settings = FakeGSettings(data=self.default_data)
+ uisettings = UISettings(settings)
+ model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)

There are a lot of these, I guess they could be moved to setUp, unless you prefer to have them there because they need slightly different parameters for each test or you like to have less context for a test.

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

Looks great! +1

Just minor stylistic notes:

#1:
+ if self._computer_title in ("", None):

you could use "if not self._computer_title" here. (there are a few of these).

#2:
+ self.assertEqual(True, state.get(IS_HOSTED))

please use assertTrue here.

#3:
+ self.config_string = "[client]\n" \

please use parentheses rather than breaking with \

+ assert(self.schema.attrib["id"] == \
+ "com.canonical.landscape-client-settings")

same here

Thanks!

review: Approve
483. By Geoff Teale

removed unused GSettings event handlers

484. By Geoff Teale

Added docstring (from Free's review)

485. By Geoff Teale

Docstring and comments on complex get/set machinary (from Free's review)

486. By Geoff Teale

Simplify empty value comparisons (from Ack's review).

487. By Geoff Teale

Replace assertEqual(True, ... with assertTrue(... (from Ack's review).

488. By Geoff Teale

Use brackets instead of line continuation (from Ack's review).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'glib-2.0'
=== added directory 'glib-2.0/schemas'
=== added file 'glib-2.0/schemas/com.canonical.landscape-client-settings.gschema.xml'
--- glib-2.0/schemas/com.canonical.landscape-client-settings.gschema.xml 1970-01-01 00:00:00 +0000
+++ glib-2.0/schemas/com.canonical.landscape-client-settings.gschema.xml 2012-02-29 16:50:20 +0000
@@ -0,0 +1,37 @@
1<?xml version="1.0" encoding="utf-8"?>
2<schemalist>
3 <schema id="com.canonical.landscape-client-settings" path="/com/canonical/landscape-client-settings/">
4 <key type="b" name="is-hosted">
5 <default>true</default>
6 <summary>Whether the client settings UI currently set to a hosted client configuration.</summary>
7 </key>
8 <key type="s" name="computer-title">
9 <default></default>
10 <summary>The title to register the machine with.</summary>
11 </key>
12 <key type="s" name="hosted-landscape-host">
13 <default>canonical.landscape.com</default>
14 <summary>The hostname of the Canonical hosted landscape system.</summary>
15 </key>
16 <key type="s" name="hosted-account-name">
17 <default></default>
18 <summary>An account name for use with the Canonical hosted landscape system.</summary>
19 </key>
20 <key type="s" name="hosted-password">
21 <default></default>
22 <summary>A password for use with the Canonical hosted landscape system</summary>
23 </key>
24 <key type="s" name="local-landscape-host">
25 <default></default>
26 <summary>The hostname of the local landscape system.</summary>
27 </key>
28 <key type="s" name="local-account-name">
29 <default></default>
30 <summary>An account name for use with the local landscape system.</summary>
31 </key>
32 <key type="s" name="local-password">
33 <default></default>
34 <summary>A password for use with the local landscape system</summary>
35 </key>
36 </schema>
37</schemalist>
038
=== modified file 'landscape/ui/controller/configuration.py'
--- landscape/ui/controller/configuration.py 2012-02-03 18:10:57 +0000
+++ landscape/ui/controller/configuration.py 2012-02-29 16:50:20 +0000
@@ -1,6 +1,9 @@
1import socket1import socket
2import threading2import threading
3from landscape.ui.model.registration.proxy import RegistrationProxy3from landscape.ui.model.registration.proxy import RegistrationProxy
4from landscape.ui.model.configuration.state import (
5 derive_url_from_host_name, derive_ping_url_from_host_name,
6 derive_server_host_name_from_url)
47
58
6class ConfigControllerLockError(Exception):9class ConfigControllerLockError(Exception):
@@ -65,7 +68,7 @@
65 """68 """
66 Default machine name to FQDN.69 Default machine name to FQDN.
67 """70 """
68 if self._computer_title is None:71 if self._computer_title in ("", None):
69 self._computer_title = self.getfqdn()72 self._computer_title = self.getfqdn()
7073
71 def default_dedicated(self):74 def default_dedicated(self):
@@ -78,9 +81,8 @@
78 self._server_host_name = self._initial_server_host_name81 self._server_host_name = self._initial_server_host_name
79 else:82 else:
80 self._server_host_name = self.DEFAULT_SERVER_HOST_NAME83 self._server_host_name = self.DEFAULT_SERVER_HOST_NAME
81 self._url = self._derive_url_from_host_name(84 self._url = derive_url_from_host_name(self._server_host_name)
82 self._server_host_name)85 self._ping_url = derive_ping_url_from_host_name(
83 self._ping_url = self._derive_ping_url_from_host_name(
84 self._server_host_name)86 self._server_host_name)
85 self.modify()87 self.modify()
8688
@@ -91,10 +93,8 @@
91 """93 """
92 if self._server_host_name != self.HOSTED_HOST_NAME:94 if self._server_host_name != self.HOSTED_HOST_NAME:
93 self._server_host_name = self.HOSTED_HOST_NAME95 self._server_host_name = self.HOSTED_HOST_NAME
94 self._url = self._derive_url_from_host_name(96 self._url = derive_url_from_host_name(self._server_host_name)
95 self._server_host_name)97 self._ping_url = derive_ping_url_from_host_name(self._server_host_name)
96 self._ping_url = self._derive_ping_url_from_host_name(
97 self._server_host_name)
98 self._account_name = self._initial_account_name98 self._account_name = self._initial_account_name
99 self.modify()99 self.modify()
100100
@@ -117,7 +117,7 @@
117 self._ping_url = self._configuration.ping_url117 self._ping_url = self._configuration.ping_url
118 if self._url:118 if self._url:
119 self._server_host_name = \119 self._server_host_name = \
120 self._derive_server_host_name_from_url(self._url)120 derive_server_host_name_from_url(self._url)
121 else:121 else:
122 self._server_host_name = self.HOSTED_HOST_NAME122 self._server_host_name = self.HOSTED_HOST_NAME
123 self._initial_server_host_name = self._server_host_name123 self._initial_server_host_name = self._server_host_name
@@ -143,29 +143,6 @@
143 self._lock.release()143 self._lock.release()
144 return lock_state144 return lock_state
145145
146 def _derive_server_host_name_from_url(self, url):
147 "Extract the hostname part from a URL."
148 try:
149 without_protocol = url[url.index("://") + 3:]
150 except ValueError:
151 without_protocol = url
152 try:
153 return without_protocol[:without_protocol.index("/")]
154 except ValueError:
155 return without_protocol
156
157 def _derive_url_from_host_name(self, host_name):
158 "Extrapolate a url from a host name."
159 #Reuse this code to make sure it's a proper host name
160 host_name = self._derive_server_host_name_from_url(host_name)
161 return "https://" + host_name + "/message-system"
162
163 def _derive_ping_url_from_host_name(self, host_name):
164 "Extrapolate a ping_url from a host name."
165 #Reuse this code to make sure it's a proper host name
166 host_name = self._derive_server_host_name_from_url(host_name)
167 return "http://" + host_name + "/ping"
168
169 def _get_server_host_name(self):146 def _get_server_host_name(self):
170 return self._server_host_name147 return self._server_host_name
171148
@@ -178,9 +155,8 @@
178 if value != self.HOSTED_HOST_NAME:155 if value != self.HOSTED_HOST_NAME:
179 self._initial_server_host_name = value156 self._initial_server_host_name = value
180 self._server_host_name = value157 self._server_host_name = value
181 self._url = self._derive_url_from_host_name(158 self._url = derive_url_from_host_name(self._server_host_name)
182 self._server_host_name)159 self._ping_url = derive_ping_url_from_host_name(
183 self._ping_url = self._derive_ping_url_from_host_name(
184 self._server_host_name)160 self._server_host_name)
185 self.modify()161 self.modify()
186 self._lock.release()162 self._lock.release()
187163
=== modified file 'landscape/ui/controller/tests/test_configuration.py'
--- landscape/ui/controller/tests/test_configuration.py 2012-02-06 22:29:12 +0000
+++ landscape/ui/controller/tests/test_configuration.py 2012-02-29 16:50:20 +0000
@@ -224,19 +224,19 @@
224 dedicated.224 dedicated.
225 """225 """
226 self.controller.load()226 self.controller.load()
227 self.assertEqual(None, self.controller.account_name)227 self.assertEqual("", self.controller.account_name)
228 self.assertEqual(None, self.controller.registration_password)228 self.assertEqual("", self.controller.registration_password)
229 self.assertEqual("landscape.canonical.com",229 self.assertEqual("landscape.canonical.com",
230 self.controller.server_host_name)230 self.controller.server_host_name)
231 self.controller.account_name = "Bungle"231 self.controller.account_name = "Bungle"
232 self.controller.default_dedicated()232 self.controller.default_dedicated()
233 self.assertEqual("standalone", self.controller.account_name)233 self.assertEqual("standalone", self.controller.account_name)
234 self.assertEqual(None, self.controller.registration_password)234 self.assertEqual("", self.controller.registration_password)
235 self.assertEqual("landscape.localdomain",235 self.assertEqual("landscape.localdomain",
236 self.controller.server_host_name)236 self.controller.server_host_name)
237 self.controller.default_hosted()237 self.controller.default_hosted()
238 self.assertEqual(None, self.controller.account_name)238 self.assertEqual("", self.controller.account_name)
239 self.assertEqual(None, self.controller.registration_password)239 self.assertEqual("", self.controller.registration_password)
240 self.assertEqual("landscape.canonical.com",240 self.assertEqual("landscape.canonical.com",
241 self.controller.server_host_name)241 self.controller.server_host_name)
242 self.controller.default_dedicated()242 self.controller.default_dedicated()
243243
=== modified file 'landscape/ui/lib/polkit.py'
--- landscape/ui/lib/polkit.py 2012-01-23 09:52:49 +0000
+++ landscape/ui/lib/polkit.py 2012-02-29 16:50:20 +0000
@@ -1,7 +1,8 @@
1import dbus1import dbus
2import dbus.service2import dbus.service
3import dbus.glib3import dbus.glib
4import gobject4
5from gi.repository import GObject
56
67
7class PolicyKitMechanism(dbus.service.Object):8class PolicyKitMechanism(dbus.service.Object):
@@ -111,5 +112,5 @@
111 """112 """
112 Invoke a L{gobject.MainLoop} to process incoming DBus events.113 Invoke a L{gobject.MainLoop} to process incoming DBus events.
113 """114 """
114 mainloop = gobject.MainLoop()115 mainloop = GObject.MainLoop()
115 mainloop.run()116 mainloop.run()
116117
=== modified file 'landscape/ui/model/configuration/mechanism.py'
--- landscape/ui/model/configuration/mechanism.py 2012-01-24 10:12:49 +0000
+++ landscape/ui/model/configuration/mechanism.py 2012-02-29 16:50:20 +0000
@@ -81,8 +81,9 @@
81 except AttributeError:81 except AttributeError:
82 return ""82 return ""
83 if value is None:83 if value is None:
84 return None84 return ""
85 return str(value)85 return str(value)
86 return ""
8687
87 @dbus.service.method(INTERFACE_NAME,88 @dbus.service.method(INTERFACE_NAME,
88 in_signature="ss",89 in_signature="ss",
8990
=== modified file 'landscape/ui/model/configuration/proxy.py'
--- landscape/ui/model/configuration/proxy.py 2012-01-24 10:10:31 +0000
+++ landscape/ui/model/configuration/proxy.py 2012-02-29 16:50:20 +0000
@@ -22,7 +22,8 @@
22 The canonical case for this is L{landscape-client-settings-ui}.22 The canonical case for this is L{landscape-client-settings-ui}.
23 """23 """
2424
25 def __init__(self, bus=None, interface=None):25 def __init__(self, bus=None, interface=None, loadargs=[]):
26 self._loadargs = loadargs
26 if bus is None:27 if bus is None:
27 self._bus = dbus.SystemBus()28 self._bus = dbus.SystemBus()
28 else:29 else:
@@ -34,7 +35,9 @@
34 self._interface = interface35 self._interface = interface
3536
36 def load(self, arglist):37 def load(self, arglist):
37 if arglist is None or len(arglist) == 0:38 if arglist is None:
39 arglist = self._loadargs
40 if len(arglist) == 0:
38 al = ""41 al = ""
39 else:42 else:
40 al = chr(0x1e).join(arglist)43 al = chr(0x1e).join(arglist)
4144
=== modified file 'landscape/ui/model/configuration/state.py'
--- landscape/ui/model/configuration/state.py 2012-02-23 11:38:49 +0000
+++ landscape/ui/model/configuration/state.py 2012-02-29 16:50:20 +0000
@@ -1,3 +1,74 @@
1import copy
2import socket
3
4from landscape.ui.model.configuration.proxy import ConfigurationProxy
5
6
7HOSTED_LANDSCAPE_HOST = "landscape.canonical.com"
8LOCAL_LANDSCAPE_HOST = ""
9
10HOSTED_ACCOUNT_NAME = ""
11LOCAL_ACCOUNT_NAME = ""
12
13HOSTED_PASSWORD = ""
14LOCAL_PASSWORD = ""
15
16HOSTED = "hosted"
17LOCAL = "local"
18IS_HOSTED = "is-hosted"
19COMPUTER_TITLE = "computer-title"
20LANDSCAPE_HOST = "landscape-host"
21ACCOUNT_NAME = "account-name"
22PASSWORD = "password"
23
24
25def get_fqdn():
26 """
27 Wrap socket.getfqdn so we can test reliably.
28 """
29 return socket.getfqdn()
30
31
32DEFAULT_DATA = {
33 IS_HOSTED: True,
34 COMPUTER_TITLE: get_fqdn(),
35 HOSTED: {
36 LANDSCAPE_HOST: HOSTED_LANDSCAPE_HOST,
37 ACCOUNT_NAME: HOSTED_ACCOUNT_NAME,
38 PASSWORD: HOSTED_PASSWORD,
39 },
40 LOCAL: {
41 LANDSCAPE_HOST: LOCAL_LANDSCAPE_HOST,
42 ACCOUNT_NAME: LOCAL_ACCOUNT_NAME,
43 PASSWORD: LOCAL_PASSWORD,
44 }
45}
46
47
48def derive_server_host_name_from_url(url):
49 "Extract the hostname part from a URL."
50 try:
51 without_protocol = url[url.index("://") + 3:]
52 except ValueError:
53 without_protocol = url
54 try:
55 return without_protocol[:without_protocol.index("/")]
56 except ValueError:
57 return without_protocol
58
59
60def derive_url_from_host_name(host_name):
61 "Extrapolate a url from a host name."
62 #Reuse this code to make sure it's a proper host name
63 host_name = derive_server_host_name_from_url(host_name)
64 return "https://" + host_name + "/message-system"
65
66
67def derive_ping_url_from_host_name(host_name):
68 "Extrapolate a ping_url from a host name."
69 #Reuse this code to make sure it's a proper host name
70 host_name = derive_server_host_name_from_url(host_name)
71 return "http://" + host_name + "/ping"
172
273
3class StateError(Exception):74class StateError(Exception):
@@ -9,15 +80,68 @@
980
10class ConfigurationState(object):81class ConfigurationState(object):
11 """82 """
12 Abstract base class for states used in the L{ConfigurationModel}.83 Base class for states used in the L{ConfigurationModel}.
13 """84 """
85 def __init__(self, data, proxy, uisettings):
86 self._data = copy.deepcopy(data)
87 self._proxy = proxy
88 self._uisettings = uisettings
89
90 def get(self, *args):
91 """
92 Retrieve only valid values from two level dictionary based tree.
93
94 This mainly served to pick up programming errors and could easily be
95 replaced with a simpler scheme.
96 """
97 arglen = len(args)
98 if arglen > 2 or arglen == 0:
99 raise TypeError(
100 "get() takes either 1 or 2 keys (%d given)" % arglen)
101 if arglen == 2: # We're looking for a leaf on a branch
102 sub_dict = None
103 if args[0] in [HOSTED, LOCAL]:
104 sub_dict = self._data.get(args[0], {})
105 sub_dict = self._data[args[0]]
106 if not isinstance(sub_dict, dict):
107 raise KeyError(
108 "Compound key [%s][%s] is invalid. The data type " +
109 "returned from the first index was %s." %
110 sub_dict.__class__.__name__)
111 return sub_dict.get(args[1], None)
112 else: # we looking for a leaf at the root
113 if args[0] in (IS_HOSTED, COMPUTER_TITLE):
114 return self._data.get(args[0], None)
115 else:
116 raise KeyError("Key [%s] is invalid. " % args[0])
117
118 def set(self, *args):
119 """
120 Set only valid values from two level dictionary based tree.
121
122 This mainly served to pick up programming errors and could easily be
123 replaced with a simpler scheme.
124 """
125 arglen = len(args)
126 if arglen < 2 or arglen > 3:
127 raise TypeError("set() takes either 1 or 2 keys and exactly 1 " +
128 "value (%d arguments given)" % arglen)
129 if arglen == 2: # We're setting a leaf attached to the root
130 self._data[args[0]] = args[1]
131 else: # We're setting a leaf on a branch
132 sub_dict = None
133 if args[0] in [HOSTED, LOCAL]:
134 sub_dict = self._data.get(args[0], {})
135 if not isinstance(sub_dict, dict):
136 raise KeyError("Compound key [%s][%s] is invalid. The data " +
137 "type returned from the first index was %s."
138 % sub_dict.__class__.__name__)
139 sub_dict[args[1]] = args[2]
140 self._data[args[0]] = sub_dict
14141
15 def load_data(self):142 def load_data(self):
16 raise NotImplementedError143 raise NotImplementedError
17144
18 def test(self, test_method):
19 raise NotImplementedError
20
21 def modify(self):145 def modify(self):
22 raise NotImplementedError146 raise NotImplementedError
23147
@@ -28,16 +152,32 @@
28 raise NotImplementedError152 raise NotImplementedError
29153
30154
31class ModifiableHelper(object):155class Helper(object):
156 """
157 Base class for all state transition helpers.
158
159 It is assumed that the Helper classes are "friends" of the
160 L{ConfigurationState} classes and can have some knowledge of their
161 internals. They shouldn't be visible to users of the
162 L{ConfigurationState}s and in general we should avoid seeing the
163 L{ConfigurationState}'s _data attribute outside this module.
164 """
165
166 def __init__(self, state):
167 self._state = state
168
169
170class ModifiableHelper(Helper):
32 """171 """
33 Allow a L{ConfigurationState}s to be modified.172 Allow a L{ConfigurationState}s to be modified.
34 """173 """
35174
36 def modify(self):175 def modify(self):
37 return ModifiedState()176 return ModifiedState(self._state._data, self._state._proxy,
38177 self._state._uisettings)
39178
40class UnloadableHelper(object):179
180class UnloadableHelper(Helper):
41 """181 """
42 Disallow loading of data into a L{ConfigurationModel}.182 Disallow loading of data into a L{ConfigurationModel}.
43 """183 """
@@ -48,7 +188,7 @@
48 " cannot be transitioned via load_data()")188 " cannot be transitioned via load_data()")
49189
50190
51class UnmodifiableHelper(object):191class UnmodifiableHelper(Helper):
52 """192 """
53 Disallow modification of a L{ConfigurationState}.193 Disallow modification of a L{ConfigurationState}.
54 """194 """
@@ -59,39 +199,17 @@
59 " cannot transition via modify()")199 " cannot transition via modify()")
60200
61201
62class TestableHelper(object):202class RevertableHelper(Helper):
63 """
64 Allow testing of a L{ConfigurationModel}.
65 """
66
67 def test(self, test_method):
68 if test_method():
69 return TestedGoodState()
70 else:
71 return TestedBadState()
72
73
74class UntestableHelper(object):
75 """
76 Disallow testing of a L{ConfigurationModel}.
77 """
78
79 def test(self, test_method):
80 raise StateError("A ConfigurationModel in " +
81 self.__class__.__name__ +
82 " cannot transition via test()")
83
84
85class RevertableHelper(object):
86 """203 """
87 Allow reverting of a L{ConfigurationModel}.204 Allow reverting of a L{ConfigurationModel}.
88 """205 """
89206
90 def revert(self):207 def revert(self):
91 return InitialisedState()208 return InitialisedState(self._state._data, self._state._proxy,
92209 self._state._uisettings)
93210
94class UnrevertableHelper(object):211
212class UnrevertableHelper(Helper):
95 """213 """
96 Disallow reverting of a L{ConfigurationModel}.214 Disallow reverting of a L{ConfigurationModel}.
97 """215 """
@@ -102,16 +220,50 @@
102 " cannot transition via revert()")220 " cannot transition via revert()")
103221
104222
105class PersistableHelper(object):223class PersistableHelper(Helper):
106 """224 """
107 Allow a L{ConfigurationModel} to persist.225 Allow a L{ConfigurationModel} to persist.
108 """226 """
109227
228 def _save_to_uisettings(self):
229 self._state._uisettings.set_is_hosted(self._state.get(IS_HOSTED))
230 self._state._uisettings.set_computer_title(
231 self._state.get(COMPUTER_TITLE))
232 self._state._uisettings.set_hosted_account_name(
233 self._state.get(HOSTED, ACCOUNT_NAME))
234 self._state._uisettings.set_hosted_password(
235 self._state.get(HOSTED, PASSWORD))
236 self._state._uisettings.set_local_landscape_host(
237 self._state.get(LOCAL, LANDSCAPE_HOST))
238 self._state._uisettings.set_local_account_name(
239 self._state.get(LOCAL, ACCOUNT_NAME))
240 self._state._uisettings.set_local_password(
241 self._state.get(LOCAL, PASSWORD))
242
243 def _save_to_config(self):
244 if self._state.get(IS_HOSTED):
245 first_key = HOSTED
246 else:
247 first_key = LOCAL
248 self._state._proxy.url = derive_url_from_host_name(
249 self._state.get(first_key, LANDSCAPE_HOST))
250 self._state._proxy.ping_url = derive_ping_url_from_host_name(
251 self._state.get(first_key, LANDSCAPE_HOST))
252 self._state._proxy.account_name = \
253 self._state.get(first_key, ACCOUNT_NAME)
254 self._state._proxy.registration_password = \
255 self._state.get(first_key, PASSWORD)
256 self._state._proxy.computer_title = self._state.get(COMPUTER_TITLE)
257 self._state._proxy.write()
258
110 def persist(self):259 def persist(self):
111 return InitialisedState()260 self._save_to_uisettings()
112261 self._save_to_config()
113262 return InitialisedState(self._state._data, self._state._proxy,
114class UnpersistableHelper(object):263 self._state._uisettings)
264
265
266class UnpersistableHelper(Helper):
115 """267 """
116 Disallow persistence of a L{ConfigurationModel}.268 Disallow persistence of a L{ConfigurationModel}.
117 """269 """
@@ -125,70 +277,20 @@
125class ModifiedState(ConfigurationState):277class ModifiedState(ConfigurationState):
126 """278 """
127 The state of a L{ConfigurationModel} whenever the user has modified some279 The state of a L{ConfigurationModel} whenever the user has modified some
128 data but hasn't yet L{test}ed or L{revert}ed.280 data but hasn't yet L{persist}ed or L{revert}ed.
129 """281 """
130282
131 _modifiable_helper = ModifiableHelper()283 def __init__(self, data, proxy, uisettings):
132 _revertable_helper = RevertableHelper()284 super(ModifiedState, self).__init__(data, proxy, uisettings)
133 _testable_helper = TestableHelper()285 self._modifiable_helper = ModifiableHelper(self)
134 _unpersistable_helper = UnpersistableHelper()286 self._revertable_helper = RevertableHelper(self)
135287 self._persistable_helper = PersistableHelper(self)
136 def modify(self):288
137 return self._modifiable_helper.modify()289 def modify(self):
138290 return self._modifiable_helper.modify()
139 def revert(self):291
140 return self._revertable_helper.revert()292 def revert(self):
141293 return self._revertable_helper.revert()
142 def test(self, test_method):
143 return self._testable_helper.test(test_method)
144
145 def persist(self):
146 return self._unpersistable_helper.persist()
147
148
149class TestedState(ConfigurationState):
150 """
151 A superclass for the two possible L{TestedStates} (L{TestedGoodState} and
152 L{TestedBadState}).
153 """
154
155 _untestable_helper = UntestableHelper()
156 _unloadable_helper = UnloadableHelper()
157 _modifiable_helper = ModifiableHelper()
158 _revertable_helper = RevertableHelper()
159
160 def test(self, test_method):
161 return self._untestable_helper.test(test_method)
162
163 def load_data(self):
164 return self._unloadable_helper.load_data()
165
166 def modify(self):
167 return self._modifiable_helper.modify()
168
169 def revert(self):
170 return self._revertable_helper.revert()
171
172
173class TestedBadState(TestedState):
174 """
175 The state of a L{ConfigurationModel} after it has been L{test}ed but that
176 L{test} has failed for some reason.
177 """
178
179 _unpersistable_helper = UnpersistableHelper()
180
181 def persist(self):
182 return self._unpersistable_helper.persist()
183
184
185class TestedGoodState(TestedState):
186 """
187 The state of a L{ConfigurationModel} after it has been L{test}ed
188 successfully.
189 """
190
191 _persistable_helper = PersistableHelper()
192294
193 def persist(self):295 def persist(self):
194 return self._persistable_helper.persist()296 return self._persistable_helper.persist()
@@ -202,10 +304,45 @@
202 finally defaults should be applied where necessary.304 finally defaults should be applied where necessary.
203 """305 """
204306
205 _modifiable_helper = ModifiableHelper()307 def __init__(self, data, proxy, uisettings):
206 _unrevertable_helper = UnrevertableHelper()308 super(InitialisedState, self).__init__(data, proxy, uisettings)
207 _testable_helper = TestableHelper()309 self._modifiable_helper = ModifiableHelper(self)
208 _unpersistable_helper = UnpersistableHelper()310 self._unrevertable_helper = UnrevertableHelper(self)
311 self._unpersistable_helper = UnpersistableHelper(self)
312 self._load_uisettings_data()
313 self._load_live_data()
314
315 def _load_uisettings_data(self):
316 self.set(IS_HOSTED, self._uisettings.get_is_hosted())
317 computer_title = self._uisettings.get_computer_title()
318 if computer_title:
319 self.set(COMPUTER_TITLE, computer_title)
320 self.set(HOSTED, LANDSCAPE_HOST,
321 self._uisettings.get_hosted_landscape_host())
322 self.set(HOSTED, ACCOUNT_NAME,
323 self._uisettings.get_hosted_account_name())
324 self.set(HOSTED, PASSWORD, self._uisettings.get_hosted_password())
325 self.set(LOCAL, LANDSCAPE_HOST,
326 self._uisettings.get_local_landscape_host())
327 self.set(LOCAL, ACCOUNT_NAME,
328 self._uisettings.get_local_account_name())
329 self.set(LOCAL, PASSWORD, self._uisettings.get_local_password())
330
331 def _load_live_data(self):
332 self._proxy.load(None)
333 computer_title = self._proxy.computer_title
334 if computer_title:
335 self.set(COMPUTER_TITLE, computer_title)
336 url = self._proxy.url
337 if url.find(HOSTED_LANDSCAPE_HOST) > -1:
338 self.set(IS_HOSTED, True)
339 self.set(HOSTED, ACCOUNT_NAME, self._proxy.account_name)
340 self.set(HOSTED, PASSWORD, self._proxy.registration_password)
341 else:
342 self.set(IS_HOSTED, False)
343 self.set(LOCAL, LANDSCAPE_HOST,
344 derive_server_host_name_from_url(url))
345 self.set(LOCAL, ACCOUNT_NAME, self._proxy.account_name)
209346
210 def load_data(self):347 def load_data(self):
211 return self348 return self
@@ -216,9 +353,6 @@
216 def revert(self):353 def revert(self):
217 return self._unrevertable_helper.revert()354 return self._unrevertable_helper.revert()
218355
219 def test(self, test_method):
220 return self._testable_helper.test(test_method)
221
222 def persist(self):356 def persist(self):
223 return self._unpersistable_helper.persist()357 return self._unpersistable_helper.persist()
224358
@@ -229,16 +363,14 @@
229 upon it.363 upon it.
230 """364 """
231365
232 _untestable_helper = UntestableHelper()366 def __init__(self, proxy, uisettings):
233 _unmodifiable_helper = UnmodifiableHelper()367 super(VirginState, self).__init__(DEFAULT_DATA, proxy, uisettings)
234 _unrevertable_helper = UnrevertableHelper()368 self._unmodifiable_helper = UnmodifiableHelper(self)
235 _unpersistable_helper = UnpersistableHelper()369 self._unrevertable_helper = UnrevertableHelper(self)
370 self._unpersistable_helper = UnpersistableHelper(self)
236371
237 def load_data(self):372 def load_data(self):
238 return InitialisedState()373 return InitialisedState(self._data, self._proxy, self._uisettings)
239
240 def test(self, test_method):
241 return self._untestable_helper.test(test_method)
242374
243 def modify(self):375 def modify(self):
244 return self._unmodifiable_helper.modify()376 return self._unmodifiable_helper.modify()
@@ -266,29 +398,15 @@
266398
267 VirginState --(load_data)--> InitialisedState399 VirginState --(load_data)--> InitialisedState
268 InitialisedState --(modify)-----> ModifiedState400 InitialisedState --(modify)-----> ModifiedState
269 InitialisedState --(test)-------> TestedGoodState
270 InitialisedState --(test)-------> TestedBadState
271 ModifiedState --(revert)-----> InitialisedState401 ModifiedState --(revert)-----> InitialisedState
272 ModifiedState --(modify)-----> ModifiedState402 ModifiedState --(modify)-----> ModifiedState
273 ModifiedState --(test)-------> TestedGoodState403 ModifiedState --(persist)----> InitialisedState
274 ModifiedState --(test)-------> TestedBadState
275 TestedGoodState --(revert)-----> InitialisedState
276 TestedGoodState --(persist)----> InitialisedState
277 TestedGoodState --(modify)-----> ModifiedState
278 TestedBadState --(revert)-----> InitialisedState
279 TestedBadState --(modify)-----> ModifiedState
280 """404 """
281405
282 def __init__(self, test_method=None):406 def __init__(self, proxy=None, proxy_loadargs=[], uisettings=None):
283 self._current_state = VirginState()407 if not proxy:
284 if test_method:408 proxy = ConfigurationProxy(loadargs=proxy_loadargs)
285 self._test_method = test_method409 self._current_state = VirginState(proxy, uisettings)
286 else:
287 self._test_method = self._test
288
289 def _test(self):
290 # TODO, dump this and use something real
291 return True
292410
293 def get_state(self):411 def get_state(self):
294 """412 """
@@ -299,9 +417,6 @@
299 def load_data(self):417 def load_data(self):
300 self._current_state = self._current_state.load_data()418 self._current_state = self._current_state.load_data()
301419
302 def test(self):
303 self._current_state = self._current_state.test(self._test_method)
304
305 def modify(self):420 def modify(self):
306 self._current_state = self._current_state.modify()421 self._current_state = self._current_state.modify()
307422
@@ -310,3 +425,73 @@
310425
311 def persist(self):426 def persist(self):
312 self._current_state = self._current_state.persist()427 self._current_state = self._current_state.persist()
428
429 def _get_is_hosted(self):
430 return self._current_state.get(IS_HOSTED)
431
432 def _set_is_hosted(self, value):
433 self._current_state.set(IS_HOSTED, value)
434
435 is_hosted = property(_get_is_hosted, _set_is_hosted)
436
437 def _get_computer_title(self):
438 return self._current_state.get(COMPUTER_TITLE)
439
440 def _set_computer_title(self, value):
441 self._current_state.set(COMPUTER_TITLE, value)
442
443 computer_title = property(_get_computer_title, _set_computer_title)
444
445 def _get_hosted_landscape_host(self):
446 return self._current_state.get(HOSTED, LANDSCAPE_HOST)
447
448 def _set_hosted_landscape_host(self, value):
449 self._current_state.set(HOSTED, LANDSCAPE_HOST, value)
450
451 hosted_landscape_host = property(_get_hosted_landscape_host,
452 _set_hosted_landscape_host)
453
454 def _get_local_landscape_host(self):
455 return self._current_state.get(LOCAL, LANDSCAPE_HOST)
456
457 def _set_local_landscape_host(self, value):
458 self._current_state.set(LOCAL, LANDSCAPE_HOST, value)
459
460 local_landscape_host = property(_get_local_landscape_host,
461 _set_local_landscape_host)
462
463 def _get_hosted_account_name(self):
464 return self._current_state.get(HOSTED, ACCOUNT_NAME)
465
466 def _set_hosted_account_name(self, value):
467 self._current_state.set(HOSTED, ACCOUNT_NAME, value)
468
469 hosted_account_name = property(_get_hosted_account_name,
470 _set_hosted_account_name)
471
472 def _get_local_account_name(self):
473 return self._current_state.get(LOCAL, ACCOUNT_NAME)
474
475 def _set_local_account_name(self, value):
476 self._current_state.set(LOCAL, ACCOUNT_NAME, value)
477
478 local_account_name = property(_get_local_account_name,
479 _set_local_account_name)
480
481 def _get_hosted_password(self):
482 return self._current_state.get(HOSTED, PASSWORD)
483
484 def _set_hosted_password(self, value):
485 self._current_state.set(HOSTED, PASSWORD, value)
486
487 hosted_password = property(_get_hosted_password,
488 _set_hosted_password)
489
490 def _get_local_password(self):
491 return self._current_state.get(LOCAL, PASSWORD)
492
493 def _set_local_password(self, value):
494 self._current_state.set(LOCAL, PASSWORD, value)
495
496 local_password = property(_get_local_password,
497 _set_local_password)
313498
=== modified file 'landscape/ui/model/configuration/tests/test_state.py'
--- landscape/ui/model/configuration/tests/test_state.py 2012-02-21 10:37:58 +0000
+++ landscape/ui/model/configuration/tests/test_state.py 2012-02-29 16:50:20 +0000
@@ -1,7 +1,293 @@
1from landscape.tests.helpers import LandscapeTest1from landscape.tests.helpers import LandscapeTest
2from landscape.ui.model.configuration.uisettings import UISettings
3import landscape.ui.model.configuration.state
2from landscape.ui.model.configuration.state import (4from landscape.ui.model.configuration.state import (
3 ConfigurationModel, StateError, VirginState, InitialisedState,5 ConfigurationModel, StateError, VirginState, InitialisedState,
4 TestedGoodState, TestedBadState, ModifiedState)6 ModifiedState, IS_HOSTED, HOSTED, LOCAL, HOSTED_LANDSCAPE_HOST,
7 LANDSCAPE_HOST, COMPUTER_TITLE)
8from landscape.ui.tests.helpers import ConfigurationProxyHelper, FakeGSettings
9
10
11class ConfigurationModelTest(LandscapeTest):
12 """
13 Test the internal data handling of the L{ConfigurationModel} without
14 loading external data.
15 """
16
17 helpers = [ConfigurationProxyHelper]
18
19 default_data = {"is-hosted": True,
20 "computer-title": "",
21 "hosted-landscape-host": "",
22 "hosted-account-name": "",
23 "hosted-password": "",
24 "local-landscape-host": "",
25 "local-account-name": "",
26 "local-password": ""
27 }
28
29 def setUp(self):
30 self.config_string = ""
31 landscape.ui.model.configuration.state.DEFAULT_DATA[COMPUTER_TITLE] \
32 = "bound.to.lose"
33 super(ConfigurationModelTest, self).setUp()
34
35 def tearDown(self):
36 super(ConfigurationModelTest, self).tearDown()
37 self.proxy = None
38
39 def test_get(self):
40 """
41 Test that L{get} correctly extracts data from the internal data storage
42 of the L{ConfigurationState}s associated with a L{ConfigurationModel}.
43 """
44 settings = FakeGSettings(data=self.default_data)
45 uisettings = UISettings(settings)
46 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
47 state = model.get_state()
48 self.assertTrue(state.get(IS_HOSTED))
49 self.assertEqual(HOSTED_LANDSCAPE_HOST,
50 state.get(HOSTED, LANDSCAPE_HOST))
51 self.assertRaises(TypeError, state.get, IS_HOSTED, HOSTED,
52 LANDSCAPE_HOST)
53 self.assertRaises(KeyError, state.get, LANDSCAPE_HOST)
54 self.assertRaises(KeyError, state.get, IS_HOSTED, LANDSCAPE_HOST)
55
56 def test_set(self):
57 """
58 Test that L{set} correctly sets data in the internal data storage of
59 the L{ConfigurationState}s associated with a L{ConfigurationModel}.
60 """
61 settings = FakeGSettings(data=self.default_data)
62 uisettings = UISettings(settings)
63 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
64 state = model.get_state()
65 state.set(IS_HOSTED, True)
66 self.assertTrue(state.get(IS_HOSTED))
67 state.set(IS_HOSTED, False)
68 self.assertFalse(state.get(IS_HOSTED))
69 self.assertEqual("", state.get(LOCAL, LANDSCAPE_HOST))
70 state.set(LOCAL, LANDSCAPE_HOST, "goodison.park")
71 self.assertEqual("goodison.park", state.get(LOCAL, LANDSCAPE_HOST))
72
73 def test_virginal(self):
74 """
75 Test that the L{ConfigurationModel} is created with default data. This
76 should be managed via L{VirginState} (hence the name), but this should
77 not be exposed and is not explicitly tested here (see
78 L{StateTransitionTest}).
79 """
80 settings = FakeGSettings(data=self.default_data)
81 uisettings = UISettings(settings)
82 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
83 self.assertTrue(model.is_hosted)
84 self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
85 self.assertEqual("bound.to.lose", model.computer_title)
86 self.assertEqual("", model.local_landscape_host)
87 self.assertEqual("", model.hosted_account_name)
88 self.assertEqual("", model.local_account_name)
89 self.assertEqual("", model.hosted_password)
90
91 def test_is_hosted_property(self):
92 """
93 Test we can use the L{is_hosted} property to set and get that data on
94 the current L{ConfigurationState}.
95 """
96 settings = FakeGSettings(data=self.default_data)
97 uisettings = UISettings(settings)
98 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
99 model.load_data()
100 self.assertTrue(model.is_hosted)
101 model.is_hosted = False
102 self.assertFalse(model.is_hosted)
103
104 def test_computer_title_property(self):
105 """
106 Test that we can use the L{computer_title} property to set and get that
107 data on the current L{ConfigurationState}.
108 """
109 settings = FakeGSettings(data=self.default_data)
110 uisettings = UISettings(settings)
111 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
112 model.load_data()
113 self.assertEqual("bound.to.lose", model.computer_title)
114 model.computer_title = "bound.to.win"
115 self.assertEqual("bound.to.win", model.computer_title)
116
117 def test_hosted_landscape_host_property(self):
118 """
119 Test we can use the L{hosted_landscape_host} property to set and get
120 that data on the current L{ConfigurationState}.
121 """
122 settings = FakeGSettings(data=self.default_data)
123 uisettings = UISettings(settings)
124 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
125 self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
126 model.hosted_landscape_host = "foo"
127 self.assertEqual("foo", model.hosted_landscape_host)
128
129 def test_hosted_account_name_property(self):
130 """
131 Test we can use the L{hosted_account_name} property to set and get
132 that data on the current L{ConfigurationState}.
133 """
134 settings = FakeGSettings(data=self.default_data)
135 uisettings = UISettings(settings)
136 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
137 self.assertEqual("", model.hosted_account_name)
138 model.hosted_account_name = "foo"
139 self.assertEqual("foo", model.hosted_account_name)
140
141 def test_hosted_password_property(self):
142 """
143 Test we can use the L{hosted_password} property to set and get
144 that data on the current L{ConfigurationState}.
145 """
146 settings = FakeGSettings(data=self.default_data)
147 uisettings = UISettings(settings)
148 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
149 self.assertEqual("", model.hosted_password)
150 model.hosted_password = "foo"
151 self.assertEqual("foo", model.hosted_password)
152
153 def test_local_landscape_host_property(self):
154 """
155 Test we can use the L{local_landscape_host} property to set and get
156 that data on the current L{ConfigurationState}.
157 """
158 settings = FakeGSettings(data=self.default_data)
159 uisettings = UISettings(settings)
160 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
161 self.assertEqual("", model.local_landscape_host)
162 model.local_landscape_host = "foo"
163 self.assertEqual("foo", model.local_landscape_host)
164
165 def test_local_account_name_property(self):
166 """
167 Test we can use the L{local_account_name} property to set and get
168 that data on the current L{ConfigurationState}.
169 """
170 settings = FakeGSettings(data=self.default_data)
171 uisettings = UISettings(settings)
172 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
173 self.assertEqual("", model.local_account_name)
174 model.local_account_name = "foo"
175 self.assertEqual("foo", model.local_account_name)
176
177 def test_local_password_property(self):
178 """
179 Test we can use the L{local_password} property to set and get
180 that data on the current L{ConfigurationState}.
181 """
182 settings = FakeGSettings(data=self.default_data)
183 uisettings = UISettings(settings)
184 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
185 self.assertEqual("", model.local_password)
186 model.local_password = "foo"
187 self.assertEqual("foo", model.local_password)
188
189
190class ConfigurationModelHostedTest(LandscapeTest):
191 """
192 Test the L{ConfigurationModel} is correctly initialised when the live
193 configuration is set for a hosted account.
194
195 Note the multilayer data loading:
196
197 1. Internal state is defaulted.
198 2. UISettings data is loaded.
199 3. Live configuration is loaded.
200 """
201
202 helpers = [ConfigurationProxyHelper]
203
204 default_data = {"is-hosted": True,
205 "computer-title": "bound.to.lose",
206 "hosted-landscape-host": "landscape.canonical.com",
207 "hosted-account-name": "Sparklehorse",
208 "hosted-password": "Vivadixiesubmarinetransmissionplot",
209 "local-landscape-host": "the.local.machine",
210 "local-account-name": "CrazyHorse",
211 "local-password": "RustNeverSleeps"
212 }
213
214 def setUp(self):
215 self.config_string = "[client]\n" \
216 "data_path = /var/lib/landscape/client/\n" \
217 "http_proxy = http://proxy.localdomain:3192\n" \
218 "tags = a_tag\n" \
219 "url = https://landscape.canonical.com/message-system\n" \
220 "account_name = foo\n" \
221 "registration_password = boink\n" \
222 "computer_title = baz\n" \
223 "https_proxy = https://proxy.localdomain:6192\n" \
224 "ping_url = http://landscape.canonical.com/ping\n"
225
226 super(ConfigurationModelHostedTest, self).setUp()
227
228 def test_initialised_hosted(self):
229 """
230 Test the L{ConfigurationModel} is correctly initialised from a proxy
231 and defaults with hosted data.
232 """
233 settings = FakeGSettings(data=self.default_data)
234 uisettings = UISettings(settings)
235 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
236 model.load_data()
237 self.assertTrue(model.is_hosted)
238 self.assertEqual("landscape.canonical.com",
239 model.hosted_landscape_host)
240 self.assertEqual("the.local.machine", model.local_landscape_host)
241 self.assertEqual("foo", model.hosted_account_name)
242 self.assertEqual("CrazyHorse", model.local_account_name)
243 self.assertEqual("boink", model.hosted_password)
244
245
246class ConfigurationModelLocalTest(LandscapeTest):
247
248 helpers = [ConfigurationProxyHelper]
249
250 default_data = {"is-hosted": True,
251 "computer-title": "bound.to.lose",
252 "hosted-landscape-host": "landscape.canonical.com",
253 "hosted-account-name": "Sparklehorse",
254 "hosted-password": "Vivadixiesubmarinetransmissionplot",
255 "local-landscape-host": "the.local.machine",
256 "local-account-name": "CrazyHorse",
257 "local-password": "RustNeverSleeps"
258 }
259
260 def setUp(self):
261 self.config_string = "[client]\n" \
262 "data_path = /var/lib/landscape/client/\n" \
263 "http_proxy = http://proxy.localdomain:3192\n" \
264 "tags = a_tag\n" \
265 "url = https://landscape.localdomain/message-system\n" \
266 "account_name = foo\n" \
267 "registration_password = boink\n" \
268 "computer_title = baz\n" \
269 "https_proxy = \n" \
270 "ping_url = http://landscape.localdomain/ping\n"
271
272 super(ConfigurationModelLocalTest, self).setUp()
273
274 def test_initialised_local(self):
275 """
276 Test the L{ConfigurationModel} is correctly initialised from a proxy
277 and defaults with local data.
278 """
279 settings = FakeGSettings(data=self.default_data)
280 uisettings = UISettings(settings)
281 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
282 model.load_data()
283 self.assertFalse(model.is_hosted)
284 self.assertEqual("landscape.canonical.com",
285 model.hosted_landscape_host)
286 self.assertEqual("landscape.localdomain", model.local_landscape_host)
287 self.assertEqual("Sparklehorse", model.hosted_account_name)
288 self.assertEqual("foo", model.local_account_name)
289 self.assertEqual("Vivadixiesubmarinetransmissionplot",
290 model.hosted_password)
5291
6292
7class StateTransitionTest(LandscapeTest):293class StateTransitionTest(LandscapeTest):
@@ -10,12 +296,30 @@
10 L{ConfigurationModel}.296 L{ConfigurationModel}.
11 """297 """
12298
299 helpers = [ConfigurationProxyHelper]
300
301 def setUp(self):
302 self.config_string = ""
303 self.default_data = {
304 "is-hosted": True,
305 "computer-title": "bound.to.lose",
306 "hosted-landscape-host": "landscape.canonical.com",
307 "hosted-account-name": "Sparklehorse",
308 "hosted-password": "Vivadixiesubmarinetransmissionplot",
309 "local-landscape-host": "the.local.machine",
310 "local-account-name": "CrazyHorse",
311 "local-password": "RustNeverSleeps"
312 }
313 super(StateTransitionTest, self).setUp()
314
13 def test_load_data_transitions(self):315 def test_load_data_transitions(self):
14 """316 """
15 Test that the L{ConfigurationModel} correctly changes state as we call317 Test that the L{ConfigurationModel} correctly changes state as we call
16 L{load_data}.318 L{load_data}.
17 """319 """
18 model = ConfigurationModel()320 settings = FakeGSettings(data=self.default_data)
321 uisettings = UISettings(settings)
322 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
19 self.assertTrue(isinstance(model.get_state(), VirginState))323 self.assertTrue(isinstance(model.get_state(), VirginState))
20 model.load_data()324 model.load_data()
21 self.assertTrue(isinstance(model.get_state(), InitialisedState))325 self.assertTrue(isinstance(model.get_state(), InitialisedState))
@@ -24,54 +328,14 @@
24 self.assertTrue(isinstance(model.get_state(), InitialisedState))328 self.assertTrue(isinstance(model.get_state(), InitialisedState))
25 self.assertIs(initialised, model.get_state())329 self.assertIs(initialised, model.get_state())
26330
27 def test_testing_a_virgin_raises(self):
28 """
29 Test that calling L{test} on a L{ConfigurationModel} in L{VirginState}
30 raises an error.
31 """
32 model = ConfigurationModel()
33 self.assertTrue(isinstance(model.get_state(), VirginState))
34 self.assertRaises(StateError, model.test)
35
36 def test_load_data_on_tested_state_raises(self):
37 """
38 Test that calling L{load_data} on a L{ConfigurationModel} in either one
39 of the two L{TestedState} subclasses (L{TestedGoodState} or
40 L{TestedBadState}) will raise a L{StateError}.
41 """
42 test_succeed = lambda: True
43 test_fail = lambda: False
44 model = ConfigurationModel(test_method=test_succeed)
45 model.load_data()
46 model.test()
47 self.assertRaises(StateError, model.load_data)
48 model = ConfigurationModel(test_method=test_fail)
49 model.load_data()
50 model.test()
51 self.assertRaises(StateError, model.load_data)
52
53 def test_test_transition(self):
54 """
55 Test that the L{ConfigurationModel} transitions to a L{TestedGoodState}
56 or a L{TestedBadState} when L{test} is called.
57 """
58 test_succeed = lambda: True
59 test_fail = lambda: False
60 model = ConfigurationModel(test_method=test_succeed)
61 model.load_data()
62 model.test()
63 self.assertTrue(isinstance(model.get_state(), TestedGoodState))
64 model = ConfigurationModel(test_method=test_fail)
65 model.load_data()
66 model.test()
67 self.assertTrue(isinstance(model.get_state(), TestedBadState))
68
69 def test_modifying_a_virgin_raises(self):331 def test_modifying_a_virgin_raises(self):
70 """332 """
71 Test that attempting a L{modify} a L{ConfigurationModel} in333 Test that attempting a L{modify} a L{ConfigurationModel} in
72 L{VirginState} raises a L{StateError}.334 L{VirginState} raises a L{StateError}.
73 """335 """
74 model = ConfigurationModel()336 settings = FakeGSettings(data=self.default_data)
337 uisettings = UISettings(settings)
338 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
75 self.assertRaises(StateError, model.modify)339 self.assertRaises(StateError, model.modify)
76340
77 def test_initialised_state_is_modifiable(self):341 def test_initialised_state_is_modifiable(self):
@@ -79,50 +343,28 @@
79 Test that the L{ConfigurationModel} transitions to L{ModifiedState}343 Test that the L{ConfigurationModel} transitions to L{ModifiedState}
80 whenever L{modify} is called on it in L{InitialisedState}.344 whenever L{modify} is called on it in L{InitialisedState}.
81 """345 """
82 model = ConfigurationModel()346 settings = FakeGSettings(data=self.default_data)
347 uisettings = UISettings(settings)
348 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
83 model.load_data()349 model.load_data()
350 self.assertTrue(model.is_hosted)
351 model.is_hosted = False
352 self.assertFalse(model.is_hosted)
84 model.modify()353 model.modify()
85 self.assertTrue(isinstance(model.get_state(), ModifiedState))354 self.assertTrue(isinstance(model.get_state(), ModifiedState))
355 self.assertFalse(model.is_hosted)
86356
87 def test_modified_state_is_modifiable(self):357 def test_modified_state_is_modifiable(self):
88 """358 """
89 Test that the L{ConfigurationModel} transitions to L{ModifiedState}359 Test that the L{ConfigurationModel} transitions to L{ModifiedState}
90 whenever L{modify} is called on it in L{ModifiedState}.360 whenever L{modify} is called on it in L{ModifiedState}.
91 """361 """
92 model = ConfigurationModel()362 settings = FakeGSettings(data=self.default_data)
93 model.load_data()363 uisettings = UISettings(settings)
94 model.modify()364 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
95 self.assertTrue(isinstance(model.get_state(), ModifiedState))365 model.load_data()
96 model.modify()366 model.modify()
97 self.assertTrue(isinstance(model.get_state(), ModifiedState))367 self.assertTrue(isinstance(model.get_state(), ModifiedState))
98
99 def test_modified_state_is_testable(self):
100 """
101 Test that the L{ConfigurationModel} can be transitioned via L{test}
102 when it is in the L{ModifiedState}.
103 """
104 model = ConfigurationModel()
105 model.load_data()
106 model.modify()
107 model.test()
108 self.assertTrue(isinstance(model.get_state(), TestedGoodState))
109
110 def test_tested_states_are_modifiable(self):
111 """
112 Test that the L{ConfigurationModel} transitions to L{ModifiedState}
113 whenever L{modify} is called on it in a subclass of L{TestedState}
114 (L{TestedGoodState} or L{TestedBadState}).
115 """
116 test_succeed = lambda: True
117 test_fail = lambda: False
118 model = ConfigurationModel(test_method=test_succeed)
119 model.load_data()
120 model.test()
121 model.modify()
122 self.assertTrue(isinstance(model.get_state(), ModifiedState))
123 model = ConfigurationModel(test_method=test_fail)
124 model.load_data()
125 model.test()
126 model.modify()368 model.modify()
127 self.assertTrue(isinstance(model.get_state(), ModifiedState))369 self.assertTrue(isinstance(model.get_state(), ModifiedState))
128370
@@ -131,7 +373,9 @@
131 Test that calling L{revert} on a L{ConfigurationModel} in373 Test that calling L{revert} on a L{ConfigurationModel} in
132 L{VirginState} raises a L{StateError}.374 L{VirginState} raises a L{StateError}.
133 """375 """
134 model = ConfigurationModel()376 settings = FakeGSettings(data=self.default_data)
377 uisettings = UISettings(settings)
378 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
135 self.assertRaises(StateError, model.revert)379 self.assertRaises(StateError, model.revert)
136380
137 def test_initialiased_state_is_unrevertable(self):381 def test_initialiased_state_is_unrevertable(self):
@@ -139,7 +383,9 @@
139 Test that calling L{revert} on a L{ConfigurationModel} in383 Test that calling L{revert} on a L{ConfigurationModel} in
140 L{InitialisedState} raises a L{StateError}.384 L{InitialisedState} raises a L{StateError}.
141 """385 """
142 model = ConfigurationModel()386 settings = FakeGSettings(data=self.default_data)
387 uisettings = UISettings(settings)
388 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
143 model.load_data()389 model.load_data()
144 self.assertRaises(StateError, model.revert)390 self.assertRaises(StateError, model.revert)
145391
@@ -148,36 +394,43 @@
148 Test that a L{ConfigurationModel} in L{ModifiedState} can be394 Test that a L{ConfigurationModel} in L{ModifiedState} can be
149 transitioned via L{revert} to L{InitialisedState}.395 transitioned via L{revert} to L{InitialisedState}.
150 """396 """
151 model = ConfigurationModel()397 settings = FakeGSettings(data=self.default_data)
398 uisettings = UISettings(settings)
399 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
152 model.load_data()400 model.load_data()
153 model.modify()401 model.modify()
154 model.revert()402 model.revert()
155 self.assertTrue(isinstance(model.get_state(), InitialisedState))403 self.assertTrue(isinstance(model.get_state(), InitialisedState))
156404
157 def test_tested_states_are_revertable(self):405 def test_reverting_reverts_data(self):
158 """406 """
159 Test that a L{ConfigurationModel} in one of the two L{TestedState}s can407 Test that transitioning via L{revert} causes the original
160 be transitioned via L{revert} to L{InitialisedState}.408 L{InitialisedState} to be restored.
161 """409 """
162 test_succeed = lambda: True410 settings = FakeGSettings(data=self.default_data)
163 test_fail = lambda: False411 uisettings = UISettings(settings)
164 model = ConfigurationModel(test_method=test_succeed)412 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
165 model.load_data()413 model.load_data()
166 model.test()414 self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
167 model.revert()415 self.assertEqual("CrazyHorse", model.local_account_name)
168 self.assertTrue(isinstance(model.get_state(), InitialisedState))416 model.hosted_landscape_host = "foo"
169 model = ConfigurationModel(test_method=test_fail)417 model.local_account_name = "bar"
170 model.load_data()418 model.modify()
171 model.test()419 self.assertEqual("foo", model.hosted_landscape_host)
172 model.revert()420 self.assertEqual("bar", model.local_account_name)
173 self.assertTrue(isinstance(model.get_state(), InitialisedState))421 model.revert()
422 self.assertTrue(isinstance(model.get_state(), InitialisedState))
423 self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
424 self.assertEqual("CrazyHorse", model.local_account_name)
174425
175 def test_persisting_a_virgin_raises(self):426 def test_persisting_a_virgin_raises(self):
176 """427 """
177 Test that a L{ConfigurationModel} in L{VirginState} will raise a428 Test that a L{ConfigurationModel} in L{VirginState} will raise a
178 L{StateError} when you attempt to transition it with L{persist}.429 L{StateError} when you attempt to transition it with L{persist}.
179 """430 """
180 model = ConfigurationModel()431 settings = FakeGSettings(data=self.default_data)
432 uisettings = UISettings(settings)
433 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
181 self.assertRaises(StateError, model.persist)434 self.assertRaises(StateError, model.persist)
182435
183 def test_persisting_initialised_state_raises(self):436 def test_persisting_initialised_state_raises(self):
@@ -185,39 +438,107 @@
185 Test that a L{ConfigurationModel} in L{IntialisedState} will raise a438 Test that a L{ConfigurationModel} in L{IntialisedState} will raise a
186 L{StateError} when you attempt to transition it with L{persist}.439 L{StateError} when you attempt to transition it with L{persist}.
187 """440 """
188 model = ConfigurationModel()441 settings = FakeGSettings(data=self.default_data)
189 model.load_data()442 uisettings = UISettings(settings)
190 self.assertRaises(StateError, model.persist)443 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
191444 model.load_data()
192 def test_persisting_modified_state_raises(self):445 self.assertRaises(StateError, model.persist)
193 """446
194 Test that a L{ConfigurationModel} in L{InitialisedState} will raise a447 def test_persisting_modified_is_allowed(self):
195 L{StateError} when you attempt to transition it with L{persist}.448 """
196 """449 Test that a L{ConfigurationModel} in L{ModifiedState} will allow itself
197 model = ConfigurationModel()450 to be transitioned with L{persist}.
198 model.load_data()451 """
199 model.modify()452 settings = FakeGSettings(data=self.default_data)
200 self.assertRaises(StateError, model.persist)453 uisettings = UISettings(settings)
201454 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
202 def test_persisting_tested_bad_state_raises(self):455 model.load_data()
203 """456 model.modify()
204 Test that a L{ConfigurationModel} in L{TestedBadState} will raise a457 model.persist()
205 L{StateError} when you attempt to transition it with L{persist}.458 self.assertTrue(isinstance(model.get_state(), InitialisedState))
206 """459
207 test_fail = lambda: False460 def test_persisting_saves_data_to_uisettings(self):
208 model = ConfigurationModel(test_method=test_fail)461 settings = FakeGSettings(data=self.default_data)
209 model.load_data()462 uisettings = UISettings(settings)
210 model.test()463 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
211 self.assertRaises(StateError, model.persist)464 model.load_data()
212465 self.assertTrue(uisettings.get_is_hosted())
213 def test_persist_tested_good_state(self):466 self.assertEqual("Sparklehorse", uisettings.get_hosted_account_name())
214 """467 self.assertEqual("Vivadixiesubmarinetransmissionplot",
215 Test that a L{ConfigurationModel} in L{TestedGoodState} can be468 uisettings.get_hosted_password())
216 transitioned via L{persist} to a L{IntialisedState}.469 self.assertEqual("the.local.machine",
217 """470 uisettings.get_local_landscape_host())
218 test_succeed = lambda: True471 self.assertEqual("CrazyHorse", uisettings.get_local_account_name())
219 model = ConfigurationModel(test_method=test_succeed)472 self.assertEqual("RustNeverSleeps", uisettings.get_local_password())
220 model.load_data()473 model.is_hosted = False
221 model.test()474 model.hosted_account_name = "ThomasPaine"
222 model.persist()475 model.hosted_password = "TheAgeOfReason"
223 self.assertTrue(isinstance(model.get_state(), InitialisedState))476 model.local_landscape_host = "another.local.machine"
477 model.local_account_name = "ThomasHobbes"
478 model.local_password = "TheLeviathan"
479 model.modify()
480 self.assertTrue(isinstance(model.get_state(), ModifiedState))
481 model.persist()
482 self.assertTrue(isinstance(model.get_state(), InitialisedState))
483 self.assertFalse(uisettings.get_is_hosted())
484 self.assertEqual("ThomasPaine", uisettings.get_hosted_account_name())
485 self.assertEqual("TheAgeOfReason", uisettings.get_hosted_password())
486 self.assertEqual("another.local.machine",
487 uisettings.get_local_landscape_host())
488 self.assertEqual("ThomasHobbes", uisettings.get_local_account_name())
489 self.assertEqual("TheLeviathan", uisettings.get_local_password())
490
491
492class StateTransitionWithExistingConfigTest(LandscapeTest):
493 """
494 Test that we handle existing configuration data correctly when
495 transitioning through L{ConfigurationModel} states.
496 """
497
498 helpers = [ConfigurationProxyHelper]
499
500 def setUp(self):
501 self.config_string = (
502 "[client]\n"
503 "data_path = /var/lib/landscape/client/\n"
504 "http_proxy = http://proxy.localdomain:3192\n"
505 "tags = a_tag\n"
506 "url = https://landscape.canonical.com/message-system\n"
507 "account_name = Sparklehorse\n"
508 "registration_password = Vivadixiesubmarinetransmissionplot\n"
509 "computer_title = baz\n"
510 "https_proxy = https://proxy.localdomain:6192\n"
511 "ping_url = http://landscape.canonical.com/ping\n")
512 self.default_data = {
513 "is-hosted": True,
514 "computer-title": "bound.to.lose",
515 "hosted-landscape-host": "landscape.canonical.com",
516 "hosted-account-name": "Sparklehorse",
517 "hosted-password": "Vivadixiesubmarinetransmissionplot",
518 "local-landscape-host": "the.local.machine",
519 "local-account-name": "CrazyHorse",
520 "local-password": "RustNeverSleeps"
521 }
522 super(StateTransitionWithExistingConfigTest, self).setUp()
523
524 def test_persisting_saves_data_to_proxy(self):
525 settings = FakeGSettings(data=self.default_data)
526 uisettings = UISettings(settings)
527 model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
528 model.load_data()
529 self.assertEqual("Sparklehorse", self.proxy.account_name)
530 self.assertEqual("Vivadixiesubmarinetransmissionplot",
531 self.proxy.registration_password)
532 model.is_hosted = False
533 model.local_account_name = "ThomasPaine"
534 model.local_password = "TheAgeOfReason"
535 model.modify()
536 self.assertTrue(isinstance(model.get_state(), ModifiedState))
537 model.persist()
538 self.assertTrue(isinstance(model.get_state(), InitialisedState))
539 self.assertFalse(model.is_hosted)
540 self.assertEqual("https://the.local.machine/message-system",
541 self.proxy.url)
542 self.assertEqual("http://the.local.machine/ping", self.proxy.ping_url)
543 self.assertEqual("ThomasPaine", self.proxy.account_name)
544 self.assertEqual("TheAgeOfReason", self.proxy.registration_password)
224545
=== added file 'landscape/ui/model/configuration/tests/test_uisettings.py'
--- landscape/ui/model/configuration/tests/test_uisettings.py 1970-01-01 00:00:00 +0000
+++ landscape/ui/model/configuration/tests/test_uisettings.py 2012-02-29 16:50:20 +0000
@@ -0,0 +1,189 @@
1from landscape.tests.helpers import LandscapeTest
2from landscape.ui.tests.helpers import FakeGSettings
3from landscape.ui.model.configuration.uisettings import UISettings
4
5
6class UISettingsTest(LandscapeTest):
7
8 default_data = {"is-hosted": True,
9 "computer-title": "bound.to.lose",
10 "hosted-landscape-host": "landscape.canonical.com",
11 "hosted-account-name": "Sparklehorse",
12 "hosted-password": "Vivadixiesubmarinetransmissionplot",
13 "local-landscape-host": "the.local.machine",
14 "local-account-name": "CrazyHorse",
15 "local-password": "RustNeverSleeps"
16 }
17
18 def test_setup(self):
19 """
20 Test that the L{GSettings.Client} is correctly initialised.
21 """
22 settings = FakeGSettings(data=self.default_data)
23 UISettings(settings)
24 self.assertTrue(settings.was_called_with_args(
25 "new", UISettings.BASE_KEY))
26
27 def test_get_is_hosted(self):
28 """
29 Test that the L{get_is_hosted} value is correctly fetched from the
30 L{GSettings.Client}.
31 """
32 settings = FakeGSettings(data=self.default_data)
33 uisettings = UISettings(settings)
34 self.assertTrue(uisettings.get_is_hosted())
35
36 def test_set_is_hosted(self):
37 """
38 Test that we can correctly use L{set_is_hosted} to write the
39 L{is_hosted} value to the L{GSettings.Client}.
40 """
41 settings = FakeGSettings(data=self.default_data)
42 uisettings = UISettings(settings)
43 self.assertTrue(uisettings.get_is_hosted())
44 uisettings.set_is_hosted(False)
45 self.assertFalse(uisettings.get_is_hosted())
46 self.assertTrue(settings.was_called_with_args(
47 "set_boolean", "is-hosted", False))
48
49 def test_get_computer_title(self):
50 """
51 Test that the L{get_computer_title} value is correctly fetched
52 from the L{GSettings.Client}.
53 """
54 settings = FakeGSettings(data=self.default_data)
55 uisettings = UISettings(settings)
56 self.assertEqual("bound.to.lose",
57 uisettings.get_computer_title())
58
59 def test_set_computer_title(self):
60 """
61 Test that L{set_computer_title} correctly sets the value of
62 L{computer_title} in the L{GSettings.Client}.
63 """
64 settings = FakeGSettings(data=self.default_data)
65 uisettings = UISettings(settings)
66 self.assertEqual("bound.to.lose", uisettings.get_computer_title())
67 uisettings.set_computer_title("Bang")
68 self.assertEqual("Bang", uisettings.get_computer_title())
69
70 def test_get_hosted_landscape_host(self):
71 """
72 Test that the L{get_hosted_landscape_host} value is correctly fetched
73 from the L{GSettings.Client}.
74 """
75 settings = FakeGSettings(data=self.default_data)
76 uisettings = UISettings(settings)
77 self.assertEqual("landscape.canonical.com",
78 uisettings.get_hosted_landscape_host())
79
80 # NOTE: There is no facility to set the hosted-landscape-host
81
82 def test_get_hosted_account_name(self):
83 """
84 Test that the L{get_hosted_account_name} value is correctly fetched
85 from the L{GSettings.Client}.
86 """
87 settings = FakeGSettings(data=self.default_data)
88 uisettings = UISettings(settings)
89 self.assertEqual("Sparklehorse",
90 uisettings.get_hosted_account_name())
91
92 def test_set_hosted_account_name(self):
93 """
94 Test that L{set_hosted_account_name} correctly sets the value of
95 L{hosted_account_name} in the L{GSettings.Client}.
96 """
97 settings = FakeGSettings(data=self.default_data)
98 uisettings = UISettings(settings)
99 self.assertEqual("Sparklehorse", uisettings.get_hosted_account_name())
100 uisettings.set_hosted_account_name("Bang")
101 self.assertEqual("Bang", uisettings.get_hosted_account_name())
102
103 def test_get_hosted_password(self):
104 """
105 Test that the L{get_hosted_password} value is correctly fetched
106 from the L{GSettings.Client}.
107 """
108 settings = FakeGSettings(data=self.default_data)
109 uisettings = UISettings(settings)
110 self.assertEqual("Vivadixiesubmarinetransmissionplot",
111 uisettings.get_hosted_password())
112
113 def test_set_hosted_password(self):
114 """
115 Test that L{set_hosted_password} correctly sets the value of
116 L{hosted_password} in the L{GSettings.Client}.
117 """
118 settings = FakeGSettings(data=self.default_data)
119 uisettings = UISettings(settings)
120 self.assertEqual("Vivadixiesubmarinetransmissionplot",
121 uisettings.get_hosted_password())
122 uisettings.set_hosted_password("Bang")
123 self.assertEqual("Bang", uisettings.get_hosted_password())
124
125 def test_get_local_landscape_host(self):
126 """
127 Test that the L{get_local_landscape_host} value is correctly fetched
128 from the L{GSettings.Client}.
129 """
130 settings = FakeGSettings(data=self.default_data)
131 uisettings = UISettings(settings)
132 self.assertEqual("the.local.machine",
133 uisettings.get_local_landscape_host())
134
135 def test_set_local_landscape_host(self):
136 """
137 Test that L{set_local_landscape_host} correctly sets the value of
138 L{local_landscape_host} in the L{GSettings.Client}.
139 """
140 settings = FakeGSettings(data=self.default_data)
141 uisettings = UISettings(settings)
142 self.assertEqual("the.local.machine",
143 uisettings.get_local_landscape_host())
144 uisettings.set_local_landscape_host("Bang")
145 self.assertEqual("Bang", uisettings.get_local_landscape_host())
146
147 def test_get_local_account_name(self):
148 """
149 Test that the L{get_local_account_name} value is correctly fetched
150 from the L{GSettings.Client}.
151 """
152 settings = FakeGSettings(data=self.default_data)
153 uisettings = UISettings(settings)
154 self.assertEqual("CrazyHorse",
155 uisettings.get_local_account_name())
156
157 def test_set_local_account_name(self):
158 """
159 Test that L{set_local_account_name} correctly sets the value of
160 L{local_account_name} in the L{GSettings.Client}.
161 """
162 settings = FakeGSettings(data=self.default_data)
163 uisettings = UISettings(settings)
164 self.assertEqual("CrazyHorse",
165 uisettings.get_local_account_name())
166 uisettings.set_local_account_name("Bang")
167 self.assertEqual("Bang", uisettings.get_local_account_name())
168
169 def test_get_local_password(self):
170 """
171 Test that the L{get_local_password} value is correctly fetched
172 from the L{GSettings.Client}.
173 """
174 settings = FakeGSettings(data=self.default_data)
175 uisettings = UISettings(settings)
176 self.assertEqual("RustNeverSleeps",
177 uisettings.get_local_password())
178
179 def test_set_local_password(self):
180 """
181 Test that L{set_local_password} correctly sets the value of
182 L{local_password} in the L{GSettings.Client}.
183 """
184 settings = FakeGSettings(data=self.default_data)
185 uisettings = UISettings(settings)
186 self.assertEqual("RustNeverSleeps",
187 uisettings.get_local_password())
188 uisettings.set_local_password("Bang")
189 self.assertEqual("Bang", uisettings.get_local_password())
0190
=== added file 'landscape/ui/model/configuration/uisettings.py'
--- landscape/ui/model/configuration/uisettings.py 1970-01-01 00:00:00 +0000
+++ landscape/ui/model/configuration/uisettings.py 2012-02-29 16:50:20 +0000
@@ -0,0 +1,57 @@
1class UISettings(object):
2 """
3 A very thin wrapper around L{GSettings} to avoid having to know the
4 L{BaseKey} and type information elsewhere. In some future version it would
5 be right to bind to change events here so we can react to people changing
6 the settings in dconf, for now that is overkill.
7 """
8
9 BASE_KEY = "com.canonical.landscape-client-settings"
10
11 def __init__(self, settings):
12 self.settings = settings.new(self.BASE_KEY)
13
14 def get_is_hosted(self):
15 return self.settings.get_boolean("is-hosted")
16
17 def set_is_hosted(self, value):
18 self.settings.set_boolean("is-hosted", value)
19
20 def get_computer_title(self):
21 return self.settings.get_string("computer-title")
22
23 def set_computer_title(self, value):
24 self.settings.set_string("computer-title", value)
25
26 def get_hosted_landscape_host(self):
27 return self.settings.get_string("hosted-landscape-host")
28
29 def get_hosted_account_name(self):
30 return self.settings.get_string("hosted-account-name")
31
32 def set_hosted_account_name(self, value):
33 self.settings.set_string("hosted-account-name", value)
34
35 def get_hosted_password(self):
36 return self.settings.get_string("hosted-password")
37
38 def set_hosted_password(self, value):
39 self.settings.set_string("hosted-password", value)
40
41 def get_local_landscape_host(self):
42 return self.settings.get_string("local-landscape-host")
43
44 def set_local_landscape_host(self, value):
45 self.settings.set_string("local-landscape-host", value)
46
47 def get_local_account_name(self):
48 return self.settings.get_string("local-account-name")
49
50 def set_local_account_name(self, value):
51 self.settings.set_string("local-account-name", value)
52
53 def get_local_password(self):
54 return self.settings.get_string("local-password")
55
56 def set_local_password(self, value):
57 self.settings.set_string("local-password", value)
058
=== modified file 'landscape/ui/tests/helpers.py'
--- landscape/ui/tests/helpers.py 2012-01-26 12:40:16 +0000
+++ landscape/ui/tests/helpers.py 2012-02-29 16:50:20 +0000
@@ -1,3 +1,6 @@
1import os
2
3from lxml import etree
1import dbus4import dbus
25
3from landscape.configuration import LandscapeSetupConfiguration6from landscape.configuration import LandscapeSetupConfiguration
@@ -50,3 +53,95 @@
50 def tear_down(self, test_case):53 def tear_down(self, test_case):
51 if not dbus_test_should_skip:54 if not dbus_test_should_skip:
52 test_case.mechanism.remove_from_connection()55 test_case.mechanism.remove_from_connection()
56
57
58class FakeGSettings(object):
59 """
60 This class impersonates a real L{gi.repostiroy.Gio.GSettings}
61 object to allow for testing code that utilises it without setting values in
62 the live DConf.
63 """
64
65 calls = {}
66
67 def __init__(self, data={}):
68 self.set_data(data)
69 tree = etree.parse(
70 os.path.join(
71 os.path.dirname(os.path.abspath(__file__)),
72 "../../../",
73 "glib-2.0/schemas/",
74 "com.canonical.landscape-client-settings.gschema.xml"))
75 root = tree.getroot()
76 self.schema = root.find("schema")
77 assert(self.schema.attrib["id"] ==
78 "com.canonical.landscape-client-settings")
79 self.keys = {}
80 for key in self.schema.findall("key"):
81 self.keys[key.attrib["name"]] = key.attrib["type"]
82
83 def check_key_data(self, name, gstype):
84 if name in self.keys:
85 if self.keys[name] == gstype:
86 return True
87 else:
88 raise ValueError("The GSchema file says %s is a %s, " +
89 "but you asked for a %s" %
90 (name, self.keys[name], gstype))
91 else:
92 raise KeyError("Can't find %s in the GSchema file!" % name)
93
94 def get_value(self, name, gstype):
95 if self.check_key_data(name, gstype):
96 return self.data[name]
97
98 def set_value(self, name, gstype, value):
99 if self.check_key_data(name, gstype):
100 self.data[name] = value
101
102 def set_data(self, data):
103 self.data = data
104
105 def _call(self, name, *args):
106 [count, arglist] = self.calls.get(name, (0, []))
107 count += 1
108 arglist.append(self._args_to_string(*args))
109 self.calls[name] = [count, arglist]
110
111 def _args_to_string(self, *args):
112 return "|".join([str(arg) for arg in args])
113
114 def new(self, key):
115 self._call("new", key)
116 return self
117
118 def connect(self, signal, callback, *args):
119 self._call("connect", signal, callback, *args)
120
121 def get_boolean(self, name):
122 self._call("get_boolean", name)
123 return self.get_value(name, "b")
124
125 def set_boolean(self, name, value):
126 self._call("set_boolean", name, value)
127 self.set_value(name, "b", value)
128
129 def get_string(self, name):
130 self._call("get_string", name)
131 return self.get_value(name, "s")
132
133 def set_string(self, name, value):
134 self._call("set_string", name, value)
135 self.set_value(name, "s", value)
136
137 def was_called(self, name):
138 return self.calls.haskey(name)
139
140 def was_called_with_args(self, name, *args):
141 try:
142 [count, arglist] = self.calls.get(name, (0, []))
143 except KeyError:
144 return False
145
146 expected_args = self._args_to_string(*args)
147 return expected_args in arglist
53148
=== modified file 'scripts/landscape-client-registration-mechanism' (properties changed: -x to +x)
=== modified file 'scripts/landscape-client-settings-mechanism' (properties changed: -x to +x)
=== modified file 'setupui.py'
--- setupui.py 2012-01-19 14:06:45 +0000
+++ setupui.py 2012-02-29 16:50:20 +0000
@@ -39,6 +39,7 @@
39 ff = open(service_path, "w")39 ff = open(service_path, "w")
40 ff.write(output)40 ff.write(output)
41 ff.close()41 ff.close()
42 os.system("glib-compile-schemas /usr/share/glib-2.0/schemas/")
4243
4344
44pkit_description = \45pkit_description = \
@@ -76,7 +77,10 @@
76 ('/usr/share/applications/',77 ('/usr/share/applications/',
77 ['applications/landscape-client-settings.desktop']),78 ['applications/landscape-client-settings.desktop']),
78 ('/usr/share/icons/hicolor/scalable/apps/',79 ('/usr/share/icons/hicolor/scalable/apps/',
79 ['icons/preferences-management-service.svg'])],80 ['icons/preferences-management-service.svg']),
81 ('/usr/share/glib-2.0/schemas/',
82 ['glib-2.0/schemas/com.canonical.landscape-client-settings.gschema.xml'])
83 ],
80 scripts=['scripts/landscape-client-settings-mechanism',84 scripts=['scripts/landscape-client-settings-mechanism',
81 'scripts/landscape-client-registration-mechanism',85 'scripts/landscape-client-registration-mechanism',
82 "scripts/landscape-client-settings-ui"],86 "scripts/landscape-client-settings-ui"],

Subscribers

People subscribed via source and target branches

to all changes: