70
70
from testtools.matchers import ContainsAll
73
class TestGenerateJSPowerTypes(MAASServerTestCase):
74
def patch_power_types(self, enum):
75
"""Make `get_power_types` return the given `enum` dict."""
76
self.patch(nodes_views, 'get_power_types').return_value = enum
78
def test_lists_power_types_as_JS_array(self):
79
power_type = factory.make_name('power')
80
self.patch_power_types({power_type: power_type})
82
'[\n"%s"\n]' % power_type,
83
nodes_views.generate_js_power_types())
85
def test_uses_power_type_names_not_descriptions(self):
86
name = factory.make_name('name')
87
description = factory.make_name('description')
88
self.patch_power_types({name: description})
89
output = nodes_views.generate_js_power_types()
90
self.assertIn(name, output)
91
self.assertNotIn(description, output)
93
def test_works_with_real_get_power_types(self):
94
self.assertIn('ipmi', nodes_views.generate_js_power_types())
96
def test_uses_comma_as_item_separator_not_as_terminator(self):
97
self.patch(nodes_views, 'get_power_types').return_value = {
98
'a': factory.make_name('a'),
99
'b': factory.make_name('b'),
102
['[', '"a",', '"b"', ']'],
103
nodes_views.generate_js_power_types().strip().split())
105
def test_sorts_entries(self):
107
factory.make_name('power'): factory.make_name('desc')
110
self.patch_power_types(power_types)
111
output = nodes_views.generate_js_power_types()
113
sorted(power_types.keys()),
115
item.rstrip(',').strip('"\'')
116
for item in output.strip('[]').strip().split()
73
120
class NodeViewsTest(MAASServerTestCase):
75
122
def set_up_oauth_token(self):
475
522
[reverse('zone-view', args=[node.zone.name])],
476
523
get_content_links(response, '#zone'))
525
def test_view_node_shows_macs(self):
527
mac = factory.make_mac_address()
529
response = self.client.get(
530
reverse('node-view', args=[mac.node.system_id]))
531
self.assertEqual(httplib.OK, response.status_code)
533
[interfaces_section] = fromstring(response.content).cssselect(
534
'#network-interfaces')
535
[listing] = get_one(interfaces_section.cssselect('span'))
536
self.assertEqual(mac.mac_address, listing.text_content().strip())
538
def test_view_node_lists_macs_as_list_items(self):
540
node = factory.make_node()
541
factory.make_mac_address('11:11:11:11:11:11', node=node)
542
factory.make_mac_address('22:22:22:22:22:22', node=node)
544
response = self.client.get(reverse('node-view', args=[node.system_id]))
545
self.assertEqual(httplib.OK, response.status_code)
547
[interfaces_section] = fromstring(response.content).cssselect(
548
'#network-interfaces')
549
[interfaces_list] = interfaces_section.cssselect('ul')
550
interfaces = interfaces_list.cssselect('li')
552
['11:11:11:11:11:11', '22:22:22:22:22:22'],
553
[interface.text_content().strip() for interface in interfaces])
555
def test_view_node_links_network_interfaces_to_networks(self):
557
network = factory.make_network()
558
mac = factory.make_mac_address(networks=[network])
560
response = self.client.get(
561
reverse('node-view', args=[mac.node.system_id]))
562
self.assertEqual(httplib.OK, response.status_code)
564
[interfaces_section] = fromstring(response.content).cssselect(
565
'#network-interfaces')
566
[interfaces_list] = interfaces_section.cssselect('ul')
567
[interface] = interfaces_list.cssselect('li')
569
"%s (on %s)" % (mac.mac_address, network.name),
570
' '.join(interface.text_content().split()))
571
[link] = interface.cssselect('a')
572
self.assertEqual(network.name, link.text_content().strip())
574
reverse('network-view', args=[network.name]),
577
def test_view_node_sorts_networks_by_name(self):
579
networks = factory.make_networks(3, sortable_name=True)
580
mac = factory.make_mac_address(networks=networks)
582
response = self.client.get(
583
reverse('node-view', args=[mac.node.system_id]))
584
self.assertEqual(httplib.OK, response.status_code)
586
sorted_names = sorted(network.name for network in networks)
587
[interfaces_section] = fromstring(response.content).cssselect(
588
'#network-interfaces')
589
[interfaces_list] = interfaces_section.cssselect('ul')
590
[interface] = interfaces_list.cssselect('li')
592
"%s (on %s)" % (mac.mac_address, ', '.join(sorted_names)),
593
' '.join(interface.text_content().split()))
478
595
def test_view_node_displays_link_to_edit_if_user_owns_node(self):
479
596
self.client_log_in()
480
597
node = factory.make_node(owner=self.logged_in_user)
586
703
node_edit_link = reverse('node-edit', args=[node.system_id])
588
705
'hostname': factory.getRandomString(),
589
'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
590
'after_commissioning_action': factory.getRandomEnum(
591
NODE_AFTER_COMMISSIONING_ACTION),
706
'architecture': make_usable_architecture(self),
593
708
response = self.client.post(node_edit_link, params)
1332
1447
["Mac address %s deleted." % mac.mac_address],
1333
1448
[message.message for message in response.context['messages']])
1450
def test_node_delete_mac_POST_disconnects_MAC_from_network(self):
1451
self.client_log_in()
1452
network = factory.make_network()
1453
node = factory.make_node(owner=self.logged_in_user)
1454
mac = factory.make_mac_address(node=node, networks=[network])
1455
response = self.client.post(
1456
reverse('mac-delete', args=[node.system_id, mac]), {'post': 'yes'})
1457
self.assertEqual(httplib.FOUND, response.status_code)
1458
self.assertIsNotNone(reload_object(network))
1336
1461
class NodeAddMacTest(MAASServerTestCase):
1376
1501
node_edit_link = reverse('node-edit', args=[node.system_id])
1378
1503
'hostname': factory.getRandomString(),
1379
'after_commissioning_action': factory.getRandomEnum(
1380
NODE_AFTER_COMMISSIONING_ACTION),
1381
1504
'power_type': factory.getRandomPowerType(),
1382
'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
1505
'architecture': make_usable_architecture(self),
1384
1507
response = self.client.post(node_edit_link, params)