def test_node_list_sorts_by_hostname(self): names = ['zero', 'one', 'five'] nodes = [factory.make_node(hostname=n) for n in names] # First check the ascending sort order sorted_nodes = sorted(nodes, key=attrgetter('hostname')) response = self.client.get( reverse('node-list'), { 'sort': 'hostname', 'dir': 'asc'}) node_links = [ reverse('node-view', args=[node.system_id]) for node in sorted_nodes] self.assertEqual( node_links, [link for link in get_content_links(response) if link.startswith('/nodes/node')]) # Now check the reverse order node_links = list(reversed(node_links)) response = self.client.get( reverse('node-list'), { 'sort': 'hostname', 'dir': 'desc'}) self.assertEqual( node_links, [link for link in get_content_links(response) if link.startswith('/nodes/node')])
def test_node_list_sorts_by_status(self): statuses = { NODE_STATUS.READY, NODE_STATUS.DECLARED, NODE_STATUS.FAILED_TESTS, } nodes = [factory.make_node(status=s) for s in statuses] # First check the ascending sort order sorted_nodes = sorted(nodes, key=attrgetter('status')) response = self.client.get( reverse('node-list'), { 'sort': 'status', 'dir': 'asc'}) node_links = [ reverse('node-view', args=[node.system_id]) for node in sorted_nodes] self.assertEqual( node_links, [link for link in get_content_links(response) if link.startswith('/nodes/node')]) # Now check the reverse order node_links = list(reversed(node_links)) response = self.client.get( reverse('node-list'), { 'sort': 'status', 'dir': 'desc'}) self.assertEqual( node_links, [link for link in get_content_links(response) if link.startswith('/nodes/node')])
def test_view_tag_num_queries_is_independent_of_num_nodes(self): tag = factory.make_tag() tag_link = reverse('tag-view', args=[tag.name]) nodegroup = factory.make_node_group() nodes = [ factory.make_node(nodegroup=nodegroup, mac=True) for i in range(20) ] for node in nodes[:10]: node.tags.add(tag) num_queries, response = self.getNumQueries(self.client.get, tag_link) self.assertEqual( 10, len([ link for link in get_content_links(response) if link.startswith('/nodes/node') ])) # Need to get the tag, and the nodes, and the macs of the nodes self.assertTrue(num_queries > 3) for node in nodes[10:]: node.tags.add(tag) num_bonus_queries, response = self.getNumQueries( self.client.get, tag_link) self.assertEqual(num_queries, num_bonus_queries) self.assertEqual( 20, len([ link for link in get_content_links(response) if link.startswith('/nodes/node') ]))
def test_zone_list_displays_links_to_zone_query(self): """Ensures zone list displays links to the right node/device lists""" self.client_log_in() [factory.make_Zone(sortable_name=True) for _ in range(3)] zones = Zone.objects.all() sorted_zones = sorted(zones, key=lambda x: x.name.lower()) response = self.client.get(reverse('zone-list')) zone_node_links = [{ 'query': ['zone:(%s)' % zone.name], } for zone in sorted_zones] zone_device_links = [{ 'query': ['zone:(%s)' % zone.name], 'tab': ['devices'] } for zone in sorted_zones] node_links_on_page = [ parse_qs(urlparse('?' + link.split('?')[1]).query) for link in get_content_links(response) if link.startswith('/#/nodes') and '&tab=devices' not in link ] device_links_on_page = [ parse_qs(urlparse('?' + link.split('?')[1]).query) for link in get_content_links(response) if link.startswith('/#/nodes') and '&tab=devices' in link ] self.assertEqual(zone_device_links, device_links_on_page) self.assertEqual(zone_node_links, node_links_on_page)
def test_node_list_contains_column_sort_links(self): # Just create a node to have something in the list factory.make_node() response = self.client.get(reverse('node-list')) sort_hostname = '?sort=hostname&dir=asc' sort_status = '?sort=status&dir=asc' self.assertIn(sort_hostname, get_content_links(response)) self.assertIn(sort_status, get_content_links(response))
def test_prefs_displays_link_to_delete_ssh_keys(self): _, keys = factory.make_user_with_keys(user=self.logged_in_user) response = self.client.get('/account/prefs/') links = get_content_links(response) for key in keys: del_key_link = reverse('prefs-delete-sshkey', args=[key.id]) self.assertIn(del_key_link, links)
def test_prefs_displays_link_to_delete_ssh_keys(self): _, keys = factory.make_user_with_keys(user=self.logged_in_user) response = self.client.get('/account/prefs/') links = get_content_links(response) for key in keys: del_key_link = reverse('prefs-delete-sshkey', args=[key.id]) self.assertIn(del_key_link, links)
def test_settings_link_to_add_license_key(self): self.client.login(user=factory.make_admin()) self.make_license_keys(3) links = get_content_links( self.client.get(reverse('settings_license_keys'))) script_add_link = reverse('license-key-add') self.assertIn(script_add_link, links)
def test_view_node_does_not_show_link_to_delete_node(self): # Only admin users can delete nodes. node = factory.make_node(owner=self.logged_in_user) node_link = reverse('node-view', args=[node.system_id]) response = self.client.get(node_link) node_delete_link = reverse('node-delete', args=[node.system_id]) self.assertNotIn(node_delete_link, get_content_links(response))
def test_logout_link_present_on_homepage(self): password = factory.make_string() user = factory.make_User(password=password) self.client.login(username=user.username, password=password) response = self.client.get(reverse('index')) logout_link = reverse('logout') self.assertIn(logout_link, get_content_links(response, element='#user-options'))
def test_settings_contains_links_to_edit(self): self.client.login(user=factory.make_admin()) keys, _ = self.make_license_keys(3) links = get_content_links( self.client.get(reverse('settings_license_keys'))) license_key_delete_links = [ reverse('license-key-edit', args=[key.osystem, key.distro_series]) for key in keys ] self.assertThat(links, ContainsAll(license_key_delete_links))
def test_zone_list_contains_edit_links(self): zones = [factory.make_zone() for i in range(3)] response = self.client.get(reverse('zone-list')) zone_edit_links = [ reverse('zone-edit', args=[zone.name]) for zone in zones] zone_delete_links = [ reverse('zone-del', args=[zone.name]) for zone in zones] all_links = get_content_links(response) self.assertThat(all_links, ContainsAll(zone_edit_links)) self.assertThat(all_links, ContainsAll(zone_delete_links))
def test_zone_detail_links_to_node_list(self): self.client_log_in() zone = factory.make_Zone() node = factory.make_Node() node.zone = zone response = self.client.get(reverse('zone-view', args=[zone.name])) zone_node_link = (reverse('index') + "#/nodes" + "?" + urlencode({'query': 'zone:(%s)' % zone.name})) all_links = get_content_links(response) self.assertIn(zone_node_link, all_links)
def test_settings_contains_links_to_delete_scripts(self): scripts = { factory.make_commissioning_script(), factory.make_commissioning_script(), } links = get_content_links(self.client.get(reverse('settings'))) script_delete_links = [ reverse('commissioning-script-delete', args=[script.id]) for script in scripts] self.assertThat(links, ContainsAll(script_delete_links))
def test_settings_contains_links_to_delete_scripts(self): self.client.login(user=factory.make_admin()) scripts = { factory.make_Script(script_type=SCRIPT_TYPE.TESTING), factory.make_Script(script_type=SCRIPT_TYPE.TESTING), } links = get_content_links(self.client.get(reverse('settings_scripts'))) script_delete_links = [ reverse('test-script-delete', args=[script.id]) for script in scripts] self.assertThat(links, ContainsAll(script_delete_links))
def test_settings_contains_links_to_delete_scripts(self): scripts = { factory.make_commissioning_script(), factory.make_commissioning_script(), } links = get_content_links(self.client.get(reverse('settings'))) script_delete_links = [ reverse('commissioning-script-delete', args=[script.id]) for script in scripts ] self.assertThat(links, ContainsAll(script_delete_links))
def test_zone_list_displays_sorted_list_of_zones(self): # Zones are alphabetically sorted on the zone list page. zones = [factory.make_zone() for i in range(3)] sorted_zones = sorted(zones, key=lambda x: x.name.lower()) response = self.client.get(reverse('zone-list')) zone_links = [ reverse('zone-view', args=[zone.name]) for zone in sorted_zones ] self.assertEqual(zone_links, [ link for link in get_content_links(response) if link.startswith('/zones/') ])
def test_zone_list_contains_edit_links(self): zones = [factory.make_zone() for i in range(3)] response = self.client.get(reverse('zone-list')) zone_edit_links = [ reverse('zone-edit', args=[zone.name]) for zone in zones ] zone_delete_links = [ reverse('zone-del', args=[zone.name]) for zone in zones ] all_links = get_content_links(response) self.assertThat(all_links, ContainsAll(zone_edit_links)) self.assertThat(all_links, ContainsAll(zone_delete_links))
def test_zone_list_displays_sorted_list_of_zones(self): # Zones are alphabetically sorted on the zone list page. zones = [factory.make_zone() for i in range(3)] sorted_zones = sorted(zones, key=lambda x: x.name.lower()) response = self.client.get(reverse('zone-list')) zone_links = [ reverse('zone-view', args=[zone.name]) for zone in sorted_zones] self.assertEqual( zone_links, [link for link in get_content_links(response) if link.startswith('/zones/')])
def test_settings_contains_links_to_delete_scripts(self): self.client.login(user=factory.make_admin()) scripts = { factory.make_Script(script_type=SCRIPT_TYPE.COMMISSIONING), factory.make_Script(script_type=SCRIPT_TYPE.COMMISSIONING), } links = get_content_links(self.client.get(reverse("settings_scripts"))) script_delete_links = [ reverse("commissioning-script-delete", args=[script.id]) for script in scripts ] self.assertThat(links, ContainsAll(script_delete_links))
def test_allocated_node_view_page_says_node_cannot_be_deleted(self): self.become_admin() node = factory.make_node( status=NODE_STATUS.ALLOCATED, owner=factory.make_user()) node_view_link = reverse('node-view', args=[node.system_id]) response = self.client.get(node_view_link) node_delete_link = reverse('node-delete', args=[node.system_id]) self.assertEqual(httplib.OK, response.status_code) self.assertNotIn(node_delete_link, get_content_links(response)) self.assertIn( "You cannot delete this node because", response.content)
def test_view_node_shows_message_for_commissioning_node(self): statuses_with_message = ( NODE_STATUS.READY, NODE_STATUS.COMMISSIONING) help_link = "https://wiki.ubuntu.com/ServerTeam/MAAS/AvahiBoot" for status in map_enum(NODE_STATUS).values(): node = factory.make_node(status=status) node_link = reverse('node-view', args=[node.system_id]) response = self.client.get(node_link) links = get_content_links(response, '#flash-messages') if status in statuses_with_message: self.assertIn(help_link, links) else: self.assertNotIn(help_link, links)
def test_node_list_num_queries_is_independent_of_num_nodes(self): nodegroup = factory.make_node_group() for i in range(10): factory.make_node(nodegroup=nodegroup, mac=True) url = reverse('node-list') num_queries, response = self.getNumQueries(self.client.get, url) # Make sure we counted at least the queries to get the nodes, the # nodegroup and the mac addresses. self.assertTrue(num_queries > 3) self.assertEqual( 10, len([link for link in get_content_links(response) if link.startswith('/nodes/node')])) # Add 10 nodes should still have the same number of queries for i in range(10): factory.make_node(nodegroup=nodegroup, mac=True) num_bonus_queries, response = self.getNumQueries(self.client.get, url) self.assertEqual(num_queries, num_bonus_queries) self.assertEqual( 20, len([link for link in get_content_links(response) if link.startswith('/nodes/node')]))
def test_zone_list_does_not_contain_edit_and_delete_links(self): zones = [factory.make_zone() for i in range(3)] response = self.client.get(reverse('zone-list')) zone_edit_links = [ reverse('zone-edit', args=[zone.name]) for zone in zones] zone_delete_links = [ reverse('zone-del', args=[zone.name]) for zone in zones] all_links = get_content_links(response) self.assertThat( all_links, MatchesAll(*[Not(Equals(link)) for link in zone_edit_links])) self.assertThat( all_links, MatchesAll(*[Not(Equals(link)) for link in zone_delete_links]))
def test_view_tag_includes_node_links(self): tag = factory.make_tag() node = factory.make_node() node.tags.add(tag) mac = factory.make_mac_address(node=node).mac_address tag_link = reverse('tag-view', args=[tag.name]) node_link = reverse('node-view', args=[node.system_id]) response = self.client.get(tag_link) doc = fromstring(response.content) content_text = doc.cssselect('#content')[0].text_content() self.assertThat( content_text, ContainsAll([mac, '%s' % node.hostname])) self.assertNotIn(node.system_id, content_text) self.assertIn(node_link, get_content_links(response))
def test_view_node_contains_tag_names(self): node = factory.make_node(owner=self.logged_in_user) tag_a = factory.make_tag() tag_b = factory.make_tag() node.tags.add(tag_a) node.tags.add(tag_b) node_link = reverse('node-view', args=[node.system_id]) response = self.client.get(node_link) doc = fromstring(response.content) tag_text = doc.cssselect('#node_tags')[0].text_content() self.assertThat(tag_text, ContainsAll([tag_a.name, tag_b.name])) self.assertItemsEqual( [reverse('tag-view', args=[t.name]) for t in (tag_a, tag_b)], [link for link in get_content_links(response) if link.startswith('/tags/')])
def test_view_tag_includes_node_links(self): tag = factory.make_tag() node = factory.make_node() node.tags.add(tag) mac = factory.make_mac_address(node=node).mac_address tag_link = reverse('tag-view', args=[tag.name]) node_link = reverse('node-view', args=[node.system_id]) response = self.client.get(tag_link) doc = fromstring(response.content) content_text = doc.cssselect('#content')[0].text_content() self.assertThat(content_text, ContainsAll([unicode(mac), '%s' % node.hostname])) self.assertNotIn(node.system_id, content_text) self.assertIn(node_link, get_content_links(response))
def test_view_tag_num_queries_is_independent_of_num_nodes(self): tag = factory.make_tag() tag_link = reverse('tag-view', args=[tag.name]) nodegroup = factory.make_node_group() nodes = [factory.make_node(nodegroup=nodegroup, mac=True) for i in range(20)] for node in nodes[:10]: node.tags.add(tag) num_queries, response = self.getNumQueries(self.client.get, tag_link) self.assertEqual( 10, len([link for link in get_content_links(response) if link.startswith('/nodes/node')])) # Need to get the tag, and the nodes, and the macs of the nodes self.assertTrue(num_queries > 3) for node in nodes[10:]: node.tags.add(tag) num_bonus_queries, response = self.getNumQueries( self.client.get, tag_link) self.assertEqual(num_queries, num_bonus_queries) self.assertEqual( 20, len([link for link in get_content_links(response) if link.startswith('/nodes/node')]))
def test_zone_list_does_not_contain_edit_and_delete_links(self): zones = [factory.make_zone() for i in range(3)] response = self.client.get(reverse('zone-list')) zone_edit_links = [ reverse('zone-edit', args=[zone.name]) for zone in zones ] zone_delete_links = [ reverse('zone-del', args=[zone.name]) for zone in zones ] all_links = get_content_links(response) self.assertThat( all_links, MatchesAll(*[Not(Equals(link)) for link in zone_edit_links])) self.assertThat( all_links, MatchesAll(*[Not(Equals(link)) for link in zone_delete_links]))
def test_settings_contains_links_to_edit_and_delete_clusters(self): nodegroups = { factory.make_node_group(status=NODEGROUP_STATUS.ACCEPTED), factory.make_node_group(status=NODEGROUP_STATUS.PENDING), factory.make_node_group(status=NODEGROUP_STATUS.REJECTED), } links = get_content_links(self.client.get(reverse('settings'))) nodegroup_edit_links = [ reverse('cluster-edit', args=[nodegroup.uuid]) for nodegroup in nodegroups] nodegroup_delete_links = [ reverse('cluster-delete', args=[nodegroup.uuid]) for nodegroup in nodegroups] self.assertThat( links, ContainsAll(nodegroup_edit_links + nodegroup_delete_links))
def test_node_list_displays_sorted_list_of_nodes(self): # Nodes are sorted on the node list page, newest first. nodes = [factory.make_node() for i in range(3)] # Explicitely set node.created since all of these node will # be created in the same transaction and thus have the same # 'created' value by default. for node in nodes: created = factory.getRandomDate() # Update node.created without calling node.save(). Node.objects.filter(id=node.id).update(created=created) nodes = reload_objects(Node, nodes) sorted_nodes = sorted(nodes, key=lambda x: x.created, reverse=True) response = self.client.get(reverse('node-list')) node_links = [ reverse('node-view', args=[node.system_id]) for node in sorted_nodes] self.assertEqual( node_links, [link for link in get_content_links(response) if link.startswith('/nodes/node')])
def test_zone_list_contains_edit_links(self): self.client_log_in(as_admin=True) zones = [factory.make_Zone() for _ in range(3)] default_zone = Zone.objects.get_default_zone() zone_edit_links = [ reverse('zone-edit', args=[zone.name]) for zone in zones ] zone_delete_links = [ reverse('zone-del', args=[zone.name]) for zone in zones ] zone_default_edit = reverse('zone-edit', args=[default_zone.name]) zone_default_delete = reverse('zone-del', args=[default_zone.name]) response = self.client.get(reverse('zone-list')) all_links = get_content_links(response) self.assertThat(all_links, ContainsAll(zone_edit_links + zone_delete_links)) self.assertThat(all_links, Not(Contains(zone_default_edit))) self.assertThat(all_links, Not(Contains(zone_default_delete)))
def test_cluster_page_contains_links_to_edit_and_delete_interfaces(self): nodegroup = factory.make_node_group() interfaces = set() for i in range(3): interface = factory.make_node_group_interface( nodegroup=nodegroup, management=NODEGROUPINTERFACE_MANAGEMENT.UNMANAGED) interfaces.add(interface) links = get_content_links( self.client.get(reverse('cluster-edit', args=[nodegroup.uuid]))) interface_edit_links = [ reverse('cluster-interface-edit', args=[nodegroup.uuid, interface.interface]) for interface in interfaces] interface_delete_links = [ reverse('cluster-interface-delete', args=[nodegroup.uuid, interface.interface]) for interface in interfaces] self.assertThat( links, ContainsAll(interface_edit_links + interface_delete_links))
def test_settings_link_to_upload_script(self): self.client.login(user=factory.make_admin()) links = get_content_links(self.client.get(reverse("settings_scripts"))) script_add_link = reverse("commissioning-script-add") self.assertIn(script_add_link, links)
def test_node_list_contains_link_to_enlist_preseed_view(self): response = self.client.get(reverse('node-list')) enlist_preseed_link = reverse('enlist-preseed-view') self.assertIn(enlist_preseed_link, get_content_links(response))
def test_node_list_contains_link_to_node_view(self): node = factory.make_node() response = self.client.get(reverse('node-list')) node_link = reverse('node-view', args=[node.system_id]) self.assertIn(node_link, get_content_links(response))
def test_settings_link_to_upload_script(self): links = get_content_links(self.client.get(reverse('settings'))) script_add_link = reverse('commissioning-script-add') self.assertIn(script_add_link, links)
def test_zone_list_does_not_contain_add_link(self): response = self.client.get(reverse('zone-list')) add_link = reverse('zone-add') self.assertNotIn(add_link, get_content_links(response))
def test_zone_detail_for_default_zone_does_not_contain_delete_link(self): self.client_log_in(as_admin=True) response = self.client.get( reverse('zone-view', args=[DEFAULT_ZONE_NAME])) zone_delete_link = reverse('zone-del', args=[DEFAULT_ZONE_NAME]) self.assertNotIn(zone_delete_link, get_content_links(response))
def test_prefs_displays_add_ssh_key_button(self): response = self.client.get('/account/prefs/') add_key_link = reverse('prefs-add-sshkey') self.assertIn(add_key_link, get_content_links(response))
def test_zone_detail_does_not_contain_edit_link(self): zone = factory.make_zone() response = self.client.get(reverse('zone-view', args=[zone.name])) zone_edit_link = reverse('zone-edit', args=[zone.name]) self.assertNotIn(zone_edit_link, get_content_links(response))
def test_zone_detail_contains_delete_link(self): zone = factory.make_zone() response = self.client.get(reverse('zone-view', args=[zone.name])) zone_delete_link = reverse('zone-del', args=[zone.name]) self.assertIn(zone_delete_link, get_content_links(response))
def test_settings_link_to_upload_script(self): self.client_log_in(as_admin=True) links = get_content_links(self.client.get(reverse('settings'))) script_add_link = reverse('commissioning-script-add') self.assertIn(script_add_link, links)
def test_contains_link_to_add_interface(self): nodegroup = factory.make_node_group() links = get_content_links( self.client.get(reverse('cluster-edit', args=[nodegroup.uuid]))) self.assertIn( reverse('cluster-interface-create', args=[nodegroup.uuid]), links)
def test_zone_list_does_not_contain_add_link(self): response = self.client.get(reverse('zone-list')) add_link = reverse('zone-add') self.assertNotIn(add_link, get_content_links(response))
def test_zone_list_contains_add_link(self): self.client_log_in(as_admin=True) response = self.client.get(reverse('zone-list')) add_link = reverse('zone-add') self.assertIn(add_link, get_content_links(response))
def test_zone_detail_contains_edit_link(self): self.client_log_in(as_admin=True) zone = factory.make_Zone() response = self.client.get(reverse('zone-view', args=[zone.name])) zone_edit_link = reverse('zone-edit', args=[zone.name]) self.assertIn(zone_edit_link, get_content_links(response))
def test_preseedview_node_displays_link_to_view_node(self): node = factory.make_node(owner=self.logged_in_user) node_preseed_link = reverse('node-preseed-view', args=[node.system_id]) response = self.client.get(node_preseed_link) node_link = reverse('node-view', args=[node.system_id]) self.assertIn(node_link, get_content_links(response))
def test_prefs_displays_add_ssh_key_button(self): response = self.client.get('/account/prefs/') add_key_link = reverse('prefs-add-sshkey') self.assertIn(add_key_link, get_content_links(response))
def test_zone_list_link_present_on_homepage(self): response = self.client.get(reverse('index')) zone_list_link = reverse('zone-list') self.assertIn( zone_list_link, get_content_links(response, element='#main-nav'))
def test_zone_detail_contains_delete_link(self): zone = factory.make_zone() response = self.client.get(reverse('zone-view', args=[zone.name])) zone_delete_link = reverse('zone-del', args=[zone.name]) self.assertIn(zone_delete_link, get_content_links(response))
def test_zone_detail_does_not_contain_edit_link(self): zone = factory.make_zone() response = self.client.get(reverse('zone-view', args=[zone.name])) zone_edit_link = reverse('zone-edit', args=[zone.name]) self.assertNotIn(zone_edit_link, get_content_links(response))
def test_zone_list_link_present_on_homepage(self): response = self.client.get(reverse('index')) zone_list_link = reverse('zone-list') self.assertIn(zone_list_link, get_content_links(response, element='#main-nav'))