3
from landscape.ui.tests.helpers import (
4
ConfigurationProxyHelper, FakeGSettings, dbus_test_should_skip,
5
dbus_skip_message, simulate_gtk_key_release, simulate_gtk_paste)
7
if not dbus_test_should_skip:
8
from gi.repository import Gtk
9
from landscape.ui.view.configuration import (
10
ClientSettingsDialog, sanitise_host_name, is_valid_host_name)
11
from landscape.ui.controller.configuration import ConfigController
12
import landscape.ui.model.configuration.state
13
from landscape.ui.model.configuration.state import (
14
COMPUTER_TITLE, ConfigurationModel)
15
from landscape.ui.model.configuration.uisettings import UISettings
17
from landscape.tests.helpers import LandscapeTest
20
class ViewFunctionsTest(LandscapeTest):
22
def test_sanitise_host_name(self):
24
Test UI level host_name sanitation.
26
self.assertEqual("foo.bar", sanitise_host_name(" foo.bar"))
27
self.assertEqual("foo.bar", sanitise_host_name("foo.bar "))
28
self.assertEqual("foo.bar", sanitise_host_name(" foo.bar "))
30
def test_is_valid_host_name_ok(self):
32
Test that valid host names cause L{is_valid_host_name} to return
35
self.assertTrue(is_valid_host_name("a"))
36
self.assertTrue(is_valid_host_name("a.b"))
37
self.assertTrue(is_valid_host_name("a.b.c"))
38
self.assertTrue(is_valid_host_name("stop-squark"))
39
self.assertTrue(is_valid_host_name("stop-squark.teale.DE"))
40
self.assertTrue(is_valid_host_name("a2.b3.c4"))
42
def test_is_valid_host_name_bad(self):
44
Test that invalid host names cause L{is_valid_host_name} to return
47
self.assertFalse(is_valid_host_name(".a"))
48
self.assertFalse(is_valid_host_name("a."))
49
self.assertFalse(is_valid_host_name("a b"))
50
self.assertFalse(is_valid_host_name("a .b"))
51
self.assertFalse(is_valid_host_name("a. b"))
53
def test_is_valid_host_name_unicode(self):
55
Test that host names containing Unicode cause L{is_valid_host_name} to
58
self.assertFalse(is_valid_host_name(u"\xc3a"))
60
if dbus_test_should_skip:
61
skip = dbus_skip_message
64
class ConfigurationViewTest(LandscapeTest):
66
helpers = [ConfigurationProxyHelper]
69
self.default_data = {"management-type": "canonical",
71
"hosted-landscape-host": "",
72
"hosted-account-name": "",
73
"hosted-password": "",
74
"local-landscape-host": "",
75
"local-account-name": "",
78
self.config_string = (
81
"http_proxy = http://proxy.localdomain:3192\n"
83
"url = https://landscape.canonical.com/message-system\n"
84
"account_name = foo\n"
85
"registration_key = bar\n"
86
"computer_title = baz\n"
87
"https_proxy = https://proxy.localdomain:6192\n"
88
"ping_url = http://landscape.canonical.com/ping\n" % sys.path[0])
90
super(ConfigurationViewTest, self).setUp()
91
landscape.ui.model.configuration.state.DEFAULT_DATA[COMPUTER_TITLE] \
93
settings = FakeGSettings(data=self.default_data)
94
self.uisettings = UISettings(settings)
95
model = ConfigurationModel(proxy=self.proxy,
96
uisettings=self.uisettings)
97
self.controller = ConfigController(model)
99
def run_gtk_eventloop(self):
100
"""Run the Gtk event loop until all events have been processed."""
101
while Gtk.events_pending():
104
def assert_paste_data_saved(self, dialog, combo, widget, attribute):
106
Paste text into specified widget then verify data is saved.
108
# Switch to local mode
109
dialog.use_type_combobox.set_active(combo)
110
self.run_gtk_eventloop()
112
simulate_gtk_paste(widget, "pasted text")
113
self.run_gtk_eventloop()
114
self.assertTrue(self.controller.is_modified)
115
self.assertEqual("pasted text", getattr(self.controller, attribute))
118
self.run_gtk_eventloop()
119
self.assertFalse(self.controller.is_modified)
123
Test that we correctly initialise the L{ConfigurationView} correctly
126
dialog = ClientSettingsDialog(self.controller)
127
content_area = dialog.get_content_area()
128
self.assertEqual("preferences-management-service",
129
dialog.get_default_icon_name())
130
children = content_area.get_children()
131
self.assertEqual(len(children), 2)
133
self.assertIsInstance(box, Gtk.Box)
134
self.assertEqual(1, dialog.use_type_combobox.get_active())
136
def test_on_combobox_changed(self):
138
Test that changes to the active selection in L{use_type_combobox}
139
result in the correct panel becoming active and visible.
141
dialog = ClientSettingsDialog(self.controller)
142
iter = dialog.liststore.get_iter(0)
143
no_service_frame = dialog.liststore.get(iter, 2)[0]
144
iter = dialog.liststore.get_iter(1)
145
hosted_service_frame = dialog.liststore.get(iter, 2)[0]
146
iter = dialog.liststore.get_iter(2)
147
local_service_frame = dialog.liststore.get(iter, 2)[0]
149
self.assertEqual(1, dialog.use_type_combobox.get_active())
150
[alignment] = dialog.register_button.get_children()
151
[hbox] = alignment.get_children()
152
[image, label] = hbox.get_children()
154
self.run_gtk_eventloop()
155
self.assertIs(hosted_service_frame, dialog.active_widget)
156
self.assertEqual(dialog.REGISTER_BUTTON_TEXT, label.get_text())
158
dialog.use_type_combobox.set_active(0)
159
self.run_gtk_eventloop()
160
self.assertIs(no_service_frame, dialog.active_widget)
161
self.assertEqual(dialog.DISABLE_BUTTON_TEXT, label.get_text())
163
dialog.use_type_combobox.set_active(2)
164
self.run_gtk_eventloop()
165
self.assertIs(local_service_frame, dialog.active_widget)
166
self.assertEqual(dialog.REGISTER_BUTTON_TEXT, label.get_text())
168
def test_modify(self):
170
Test that modifications to data in the UI are propagated to the
173
dialog = ClientSettingsDialog(self.controller)
174
self.run_gtk_eventloop()
175
self.assertFalse(self.controller.is_modified)
176
self.assertEqual(1, dialog.use_type_combobox.get_active())
177
dialog.use_type_combobox.set_active(2)
178
self.run_gtk_eventloop()
179
self.assertTrue(self.controller.is_modified)
181
self.run_gtk_eventloop()
182
self.assertFalse(self.controller.is_modified)
183
simulate_gtk_key_release(dialog.hosted_account_name_entry, "A")
184
self.run_gtk_eventloop()
185
self.assertTrue(self.controller.is_modified)
187
self.run_gtk_eventloop()
188
self.assertFalse(self.controller.is_modified)
189
simulate_gtk_key_release(dialog.hosted_password_entry, "B")
190
self.run_gtk_eventloop()
191
self.assertTrue(self.controller.is_modified)
193
self.run_gtk_eventloop()
194
self.assertFalse(self.controller.is_modified)
195
simulate_gtk_key_release(dialog.local_landscape_host_entry, "C")
196
self.run_gtk_eventloop()
197
self.assertTrue(self.controller.is_modified)
199
def test_modify_with_paste(self):
201
Non-keypress modifications to data in the UI are propagated to the
204
dialog = ClientSettingsDialog(self.controller)
205
self.run_gtk_eventloop()
206
self.assertFalse(self.controller.is_modified)
207
self.assertEqual(1, dialog.use_type_combobox.get_active())
208
# Test hosted account name
209
self.assert_paste_data_saved(dialog, 1,
210
dialog.hosted_account_name_entry,
211
"hosted_account_name")
212
# Test hosted password
213
self.assert_paste_data_saved(dialog, 1,
214
dialog.hosted_password_entry,
216
# Test local hostname
217
self.assert_paste_data_saved(dialog, 2,
218
dialog.local_landscape_host_entry,
219
"local_landscape_host")
220
# Test local password
221
self.assert_paste_data_saved(dialog, 2,
222
dialog.local_password_entry,
225
def test_load_data_from_config(self):
227
Test that we load data into the appropriate entries from the
230
dialog = ClientSettingsDialog(self.controller)
231
self.assertEqual(1, dialog.use_type_combobox.get_active())
232
self.assertEqual("foo", dialog.hosted_account_name_entry.get_text())
233
self.assertEqual("bar", dialog.hosted_password_entry.get_text())
234
self.assertEqual("", dialog.local_landscape_host_entry.get_text())
235
self.assertEqual("", dialog.local_password_entry.get_text())
237
def test_revert(self):
239
Test that we can revert the UI values using the controller.
241
dialog = ClientSettingsDialog(self.controller)
242
self.run_gtk_eventloop()
243
self.assertEqual(1, dialog.use_type_combobox.get_active())
244
self.assertEqual("foo", dialog.hosted_account_name_entry.get_text())
245
self.assertEqual("bar", dialog.hosted_password_entry.get_text())
246
dialog.use_type_combobox.set_active(2)
247
dialog.local_landscape_host_entry.set_text("more.barn")
248
self.run_gtk_eventloop()
249
self.assertEqual("bar", dialog.hosted_password_entry.get_text())
250
self.assertEqual("more.barn",
251
dialog.local_landscape_host_entry.get_text())
253
self.run_gtk_eventloop()
254
self.assertEqual(1, dialog.use_type_combobox.get_active())
255
self.assertEqual("foo", dialog.hosted_account_name_entry.get_text())
256
self.assertEqual("bar", dialog.hosted_password_entry.get_text())
258
def test_check_local_landscape_host_name_entry_ok(self):
260
Test that L{check_local_landscape_host_name_entry} returns L{True} when
261
the input is a valid host name.
263
dialog = ClientSettingsDialog(self.controller)
264
dialog.use_type_combobox.set_active(2)
265
dialog.local_landscape_host_entry.set_text("foo.bar")
266
self.assertTrue(dialog.check_local_landscape_host_name_entry())
268
def test_check_local_landscape_host_name_entry_ok_not_recorded(self):
270
Test that L{check_local_landscape_host_name_entry} does not add the
271
entry to L{ClientSettingsDialog._errored_entries} when the input is a
274
dialog = ClientSettingsDialog(self.controller)
275
dialog.use_type_combobox.set_active(2)
276
dialog.local_landscape_host_entry.set_text("foo.bar")
277
dialog.check_local_landscape_host_name_entry()
278
self.assertEqual(0, len(dialog._errored_entries))
280
def test_check_local_landscape_host_name_entry_bad_host_name(self):
282
Test that L{check_local_landscape_host_name_entry} returns L{False}
283
when the input is not a valid host name.
285
dialog = ClientSettingsDialog(self.controller)
286
dialog.use_type_combobox.set_active(2)
287
dialog.local_landscape_host_entry.set_text("foo bar")
288
self.assertFalse(dialog.check_local_landscape_host_name_entry())
290
def test_check_local_landscape_host_name_entry_bad_recorded(self):
292
Test that L{check_local_landscape_host_name_entry} does add the
293
entry to L{ClientSettingsDialog._errored_entries} when the input is not
296
dialog = ClientSettingsDialog(self.controller)
297
dialog.use_type_combobox.set_active(2)
298
dialog.local_landscape_host_entry.set_text("foo bar")
299
dialog.check_local_landscape_host_name_entry()
300
self.assertEqual(1, len(dialog._errored_entries))
302
def test_check_local_landscape_host_name_entry_bad_error_type(self):
304
Test that L{check_local_landscape_host_name_entry} adds the correct
305
error type to L{ClientSettingsDialog._validation_errors} when the input
306
is not a valid host name.
308
dialog = ClientSettingsDialog(self.controller)
309
dialog.use_type_combobox.set_active(2)
310
dialog.local_landscape_host_entry.set_text("foo bar")
311
dialog.check_local_landscape_host_name_entry()
312
self.assertEqual(set([dialog.INVALID_HOST_NAME]),
313
dialog._validation_errors)
315
def test_check_local_landscape_host_name_entry_unicode_in_host_name(self):
317
Test that L{check_local_landscape_host_name_entry} returns L{False}
318
when the input contains Unicode.
320
dialog = ClientSettingsDialog(self.controller)
321
dialog.use_type_combobox.set_active(2)
322
dialog.local_landscape_host_entry.set_text(u"f\xc3.bar")
323
self.assertFalse(dialog.check_local_landscape_host_name_entry())
325
def test_check_local_landscape_host_name_entry_unicode_recorded(self):
327
Test that L{check_local_landscape_host_name_entry} does add the
328
entry to L{ClientSettingsDialog._errored_entries} when the input
331
dialog = ClientSettingsDialog(self.controller)
332
dialog.use_type_combobox.set_active(2)
333
dialog.local_landscape_host_entry.set_text(u"f\xc3.bar")
334
dialog.check_local_landscape_host_name_entry()
335
self.assertEqual(1, len(dialog._errored_entries))
337
def test_check_local_landscape_host_name_entry_unicode_error_type(self):
339
Test that L{check_local_landscape_host_name_entry} adds the correct
340
error type to L{ClientSettingsDialog._validation_errors} when the input
343
dialog = ClientSettingsDialog(self.controller)
344
dialog.use_type_combobox.set_active(2)
345
dialog.local_landscape_host_entry.set_text(u"f\xc3.bar")
346
dialog.check_local_landscape_host_name_entry()
348
set([dialog.INVALID_HOST_NAME, dialog.UNICODE_IN_ENTRY]),
349
dialog._validation_errors)
351
def test_check_entry_ok(self):
353
Test that we return L{True} when the text of a L{Gtk.Entry} is valid
356
dialog = ClientSettingsDialog(self.controller)
357
self.run_gtk_eventloop()
358
dialog.use_type_combobox.set_active(1)
359
self.run_gtk_eventloop()
360
dialog.hosted_account_name_entry.set_text("Toodleoo")
361
self.assertTrue(dialog.check_entry(dialog.hosted_account_name_entry))
363
def test_check_entry_doesnt_record_entry_when_ok(self):
365
Test that, when the text of a L{Gtk.Entry} is valid nothing is added to
366
L{ClientSettingsDialog._errored_entries}.
368
dialog = ClientSettingsDialog(self.controller)
369
self.run_gtk_eventloop()
370
dialog.use_type_combobox.set_active(1)
371
self.run_gtk_eventloop()
372
dialog.hosted_account_name_entry.set_text("Toodleoo")
373
dialog.check_entry(dialog.hosted_account_name_entry)
374
self.assertEqual(0, len(dialog._errored_entries))
376
def test_check_entry_non_ascii(self):
378
Test that we return L{False} when the text of a L{Gtk.Entry} contains
381
dialog = ClientSettingsDialog(self.controller)
382
self.run_gtk_eventloop()
383
dialog.use_type_combobox.set_active(1)
384
self.run_gtk_eventloop()
385
dialog.hosted_account_name_entry.set_text(u"T\xc3dle\xc4")
386
self.assertFalse(dialog.check_entry(dialog.hosted_account_name_entry))
388
def test_check_entry_records_entry_when_non_ascii(self):
390
Test that, when the text of a L{Gtk.Entry} contains Unicode it is
391
added to L{ClientSettingsDialog._errored_entries}.
393
dialog = ClientSettingsDialog(self.controller)
394
self.run_gtk_eventloop()
395
dialog.use_type_combobox.set_active(1)
396
self.run_gtk_eventloop()
397
dialog.hosted_account_name_entry.set_text(u"T\xc3dle\xc4")
398
dialog.check_entry(dialog.hosted_account_name_entry)
399
self.assertEqual(1, len(dialog._errored_entries))
401
def test_dismiss_validation_errors_local(self):
403
Test that dismissing the validation errors tidies up indicators that
404
have been set against local settings.
406
dialog = ClientSettingsDialog(self.controller)
407
self.run_gtk_eventloop()
408
dialog.use_type_combobox.set_active(1)
409
self.run_gtk_eventloop()
410
dialog.hosted_account_name_entry.set_text(u"T\xc3dle\xc4")
411
dialog.hosted_password_entry.set_text(u"T\xc3dle\xc4")
412
self.run_gtk_eventloop()
413
dialog.validity_check()
414
self.run_gtk_eventloop()
415
self.assertEqual(2, len(dialog._errored_entries))
416
[entry1, entry2] = dialog._errored_entries
417
self.assertEqual(Gtk.STOCK_DIALOG_WARNING,
418
entry1.get_icon_stock(Gtk.EntryIconPosition.PRIMARY))
419
self.assertEqual(Gtk.STOCK_DIALOG_WARNING,
420
entry2.get_icon_stock(Gtk.EntryIconPosition.PRIMARY))
421
dialog.dismiss_infobar(None)
422
self.run_gtk_eventloop()
423
self.assertEqual(0, len(dialog._errored_entries))
425
Gtk.STOCK_DIALOG_WARNING,
426
entry1.get_icon_stock(Gtk.EntryIconPosition.PRIMARY))
428
Gtk.STOCK_DIALOG_WARNING,
429
entry2.get_icon_stock(Gtk.EntryIconPosition.PRIMARY))
431
def test_dismiss_validation_errors_hosted(self):
433
Test that dismissing the validation errors tidies up indicators that
434
have been set against hosted fields.
436
dialog = ClientSettingsDialog(self.controller)
437
self.run_gtk_eventloop()
438
dialog.use_type_combobox.set_active(2)
439
self.run_gtk_eventloop()
440
dialog.local_landscape_host_entry.set_text("dodgy as hell")
441
self.run_gtk_eventloop()
442
dialog.validity_check()
443
self.run_gtk_eventloop()
444
self.assertEqual(1, len(dialog._errored_entries))
445
[entry1] = dialog._errored_entries
446
self.assertEqual(Gtk.STOCK_DIALOG_WARNING,
447
entry1.get_icon_stock(Gtk.EntryIconPosition.PRIMARY))
448
dialog.dismiss_infobar(None)
449
self.run_gtk_eventloop()
450
self.assertEqual(0, len(dialog._errored_entries))
452
Gtk.STOCK_DIALOG_WARNING,
453
entry1.get_icon_stock(Gtk.EntryIconPosition.PRIMARY))
455
def test_validity_check_disabled(self):
457
Test that the L{validity_check} returns True when we disable landscape
460
dialog = ClientSettingsDialog(self.controller)
461
self.run_gtk_eventloop()
462
dialog.use_type_combobox.set_active(0)
463
self.run_gtk_eventloop()
464
self.assertTrue(dialog.validity_check())
466
def test_validity_check_hosted(self):
468
Test that the L{validity_check} returns True when the hosted fields are
471
dialog = ClientSettingsDialog(self.controller)
472
self.run_gtk_eventloop()
473
dialog.use_type_combobox.set_active(1)
474
dialog.hosted_account_name_entry.set_text("Bob")
475
dialog.hosted_password_entry.set_text("the builder")
476
self.run_gtk_eventloop()
477
self.assertTrue(dialog.validity_check())
479
def test_validity_check_hosted_unicode(self):
481
Test that the L{validity_check} returns False when the hosted fields
484
dialog = ClientSettingsDialog(self.controller)
485
self.run_gtk_eventloop()
486
dialog.use_type_combobox.set_active(1)
487
dialog.hosted_account_name_entry.set_text(u"B\xc3b")
488
self.run_gtk_eventloop()
489
self.assertFalse(dialog.validity_check())
491
def test_validity_check_local_ok(self):
493
Test that the L{validity_check} returns True when the local fields
496
dialog = ClientSettingsDialog(self.controller)
497
self.run_gtk_eventloop()
498
dialog.use_type_combobox.set_active(2)
499
self.run_gtk_eventloop()
500
dialog.local_landscape_host_entry.set_text("foo.bar")
501
self.run_gtk_eventloop()
502
self.assertTrue(dialog.validity_check())
504
def test_validity_check_local_sanitisable(self):
506
Test that the L{validity_check} returns True when the local fields
507
are valid after sanitation.
509
dialog = ClientSettingsDialog(self.controller)
510
self.run_gtk_eventloop()
511
dialog.use_type_combobox.set_active(2)
512
dialog.local_landscape_host_entry.set_text(" foo.bar")
513
self.run_gtk_eventloop()
514
self.assertTrue(dialog.validity_check())
515
dialog.local_landscape_host_entry.set_text("foo.bar ")
516
self.run_gtk_eventloop()
517
self.assertTrue(dialog.validity_check())
519
def test_validity_check_local_invalid_host_name(self):
521
Test that the L{validity_check} returns False when the host name is
524
dialog = ClientSettingsDialog(self.controller)
525
self.run_gtk_eventloop()
526
dialog.use_type_combobox.set_active(2)
527
dialog.local_landscape_host_entry.set_text("foo bar")
528
self.run_gtk_eventloop()
529
self.assertFalse(dialog.validity_check())
531
def test_validity_check_local_unicode(self):
533
Test that the L{validity_check} returns False when the host name
536
dialog = ClientSettingsDialog(self.controller)
537
self.run_gtk_eventloop()
538
dialog.use_type_combobox.set_active(2)
539
dialog.local_landscape_host_entry.set_text(u"f\xc3.bar")
540
self.run_gtk_eventloop()
541
self.assertFalse(dialog.validity_check())
543
if dbus_test_should_skip:
544
skip = dbus_skip_message
547
class LocalConfigurationViewTest(LandscapeTest):
549
helpers = [ConfigurationProxyHelper]
552
self.default_data = {"management-type": "LDS",
553
"computer-title": "",
554
"hosted-landscape-host": "",
555
"hosted-account-name": "",
556
"hosted-password": "",
557
"local-landscape-host": "",
558
"local-account-name": "",
559
"local-password": "manky"}
561
self.config_string = (
564
"url = https://landscape.localdomain/message-system\n"
565
"computer_title = baz\n"
566
"ping_url = http://landscape.localdomain/ping\n" % sys.path[0])
568
super(LocalConfigurationViewTest, self).setUp()
569
landscape.ui.model.configuration.state.DEFAULT_DATA[COMPUTER_TITLE] \
571
settings = FakeGSettings(data=self.default_data)
572
self.uisettings = UISettings(settings)
573
model = ConfigurationModel(proxy=self.proxy,
574
uisettings=self.uisettings)
575
self.controller = ConfigController(model)
579
Test that we correctly initialise the L{ConfigurationView} correctly
582
dialog = ClientSettingsDialog(self.controller)
583
while Gtk.events_pending():
585
content_area = dialog.get_content_area()
586
children = content_area.get_children()
587
self.assertEqual(len(children), 2)
589
self.assertIsInstance(box, Gtk.Box)
590
self.assertEqual(2, dialog.use_type_combobox.get_active())
592
def test_load_data_from_config(self):
594
Test that we load data into the appropriate entries from the
597
dialog = ClientSettingsDialog(self.controller)
598
while Gtk.events_pending():
600
self.assertEqual(2, dialog.use_type_combobox.get_active())
601
self.assertEqual("", dialog.hosted_account_name_entry.get_text())
602
self.assertEqual("", dialog.hosted_password_entry.get_text())
603
self.assertEqual("landscape.localdomain",
604
dialog.local_landscape_host_entry.get_text())
605
self.assertEqual("manky", dialog.local_password_entry.get_text())
607
if dbus_test_should_skip:
608
skip = dbus_skip_message