text: # vim: tabstop=4 shiftwidth=4 softtabstop=4
  
  # Copyright 2012 United States Government as represented by the
  # Administrator of the National Aeronautics and Space Administration.
  # All Rights Reserved.
  #
  # Copyright 2012 Openstack, LLC
  # Copyright 2012 Nebula, Inc.
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file except in compliance with the License. You may obtain
  #    a copy of the License at
  #
  #         http://www.apache.org/licenses/LICENSE-2.0
  #
  #    Unless required by applicable law or agreed to in writing, software
  #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  #    License for the specific language governing permissions and limitations
  #    under the License.
  
  from django.conf import settings
  from django.core import urlresolvers
  from django import http
  from django.test.client import Client
  from django.utils.importlib import import_module
  from mox import IsA
  
  import horizon
  from horizon import api
  from horizon import base
  from horizon import test
  from horizon import users
  
  
  class MyDash(horizon.Dashboard):
      name = "My Dashboard"
      slug = "mydash"
      default_panel = "myslug"
  
  
  class MyPanel(horizon.Panel):
      name = "My Panel"
      slug = "myslug"
      services = ("compute",)
      urls = 'horizon.tests.test_panel_urls'
  
  
  class BaseHorizonTests(test.TestCase):
      def setUp(self):
          super(BaseHorizonTests, self).setUp()
          # Trigger discovery, registration, and URLconf generation if it
          # hasn't happened yet.
          base.Horizon._urls()
          # Store our original dashboards
          self._discovered_dashboards = base.Horizon._registry.keys()
          # Gather up and store our original panels for each dashboard
          self._discovered_panels = {}
          for dash in self._discovered_dashboards:
              panels = base.Horizon._registry[dash]._registry.keys()
              self._discovered_panels[dash] = panels
  
      def tearDown(self):
          super(BaseHorizonTests, self).tearDown()
          # Destroy our singleton and re-create it.
          base.HorizonSite._instance = None
          del base.Horizon
          base.Horizon = base.HorizonSite()
          # Reload the convenience references to Horizon stored in __init__
          reload(import_module("horizon"))
          # Re-register our original dashboards and panels.
          # This is necessary because autodiscovery only works on the first
          # import, and calling reload introduces innumerable additional
          # problems. Manual re-registration is the only good way for testing.
          for dash in self._discovered_dashboards:
              base.Horizon.register(dash)
              for panel in self._discovered_panels[dash]:
                  dash.register(panel)
  
      def _reload_urls(self):
          '''
          Clears out the URL caches, reloads the root urls module, and
          re-triggers the autodiscovery mechanism for Horizon. Allows URLs
          to be re-calculated after registering new dashboards. Useful
          only for testing and should never be used on a live site.
          '''
          urlresolvers.clear_url_caches()
          reload(import_module(settings.ROOT_URLCONF))
          base.Horizon._urls()
  
  
  class HorizonTests(BaseHorizonTests):
      def test_registry(self):
          """ Verify registration and autodiscovery work correctly.
  
          Please note that this implicitly tests that autodiscovery works
          by virtue of the fact that the dashboards listed in
          ``settings.INSTALLED_APPS`` are loaded from the start.
          """
          # Registration
          self.assertEqual(len(base.Horizon._registry), 3)
          horizon.register(MyDash)
          self.assertEqual(len(base.Horizon._registry), 4)
          with self.assertRaises(ValueError):
              horizon.register(MyPanel)
          with self.assertRaises(ValueError):
              horizon.register("MyPanel")
  
          # Retrieval
          my_dash_instance_by_name = horizon.get_dashboard("mydash")
          self.assertTrue(isinstance(my_dash_instance_by_name, MyDash))
          my_dash_instance_by_class = horizon.get_dashboard(MyDash)
          self.assertEqual(my_dash_instance_by_name, my_dash_instance_by_class)
          with self.assertRaises(base.NotRegistered):
              horizon.get_dashboard("fake")
          self.assertQuerysetEqual(horizon.get_dashboards(),
                                   ['<Dashboard: nova>',
                                    '<Dashboard: syspanel>',
                                    '<Dashboard: settings>',
                                    '<Dashboard: mydash>'])
  
          # Removal
          self.assertEqual(len(base.Horizon._registry), 4)
          horizon.unregister(MyDash)
          self.assertEqual(len(base.Horizon._registry), 3)
          with self.assertRaises(base.NotRegistered):
              horizon.get_dashboard(MyDash)
  
      def test_site(self):
          self.assertEqual(unicode(base.Horizon), "Horizon")
          self.assertEqual(repr(base.Horizon), "<Site: horizon>")
          dash = base.Horizon.get_dashboard('nova')
          self.assertEqual(base.Horizon.get_default_dashboard(), dash)
          user = users.User()
          self.assertEqual(base.Horizon.get_user_home(user),
                           dash.get_absolute_url())
  
      def test_dashboard(self):
          syspanel = horizon.get_dashboard("syspanel")
          self.assertEqual(syspanel._registered_with, base.Horizon)
          self.assertQuerysetEqual(syspanel.get_panels(),
                                   ['<Panel: overview>',
                                   '<Panel: instances>',
                                   '<Panel: services>',
                                   '<Panel: flavors>',
                                   '<Panel: images>',
                                   '<Panel: projects>',
                                   '<Panel: users>',
                                   '<Panel: quotas>'])
          self.assertEqual(syspanel.get_absolute_url(), "/syspanel/")
  
          # Test registering a module with a dashboard that defines panels
          # as a dictionary.
          syspanel.register(MyPanel)
          self.assertQuerysetEqual(syspanel.get_panel_groups()['other'],
                                   ['<Panel: myslug>'])
  
          # Test that panels defined as a tuple still return a PanelGroup
          settings_dash = horizon.get_dashboard("settings")
          self.assertQuerysetEqual(settings_dash.get_panel_groups().values(),
                                   ['<PanelGroup: default>'])
  
          # Test registering a module with a dashboard that defines panels
          # as a tuple.
          settings_dash = horizon.get_dashboard("settings")
          settings_dash.register(MyPanel)
          self.assertQuerysetEqual(settings_dash.get_panels(),
                                   ['<Panel: user>',
                                    '<Panel: project>',
                                    '<Panel: ec2>',
                                    '<Panel: myslug>'])
  
      def test_panels(self):
          syspanel = horizon.get_dashboard("syspanel")
          instances = syspanel.get_panel("instances")
          self.assertEqual(instances._registered_with, syspanel)
          self.assertEqual(instances.get_absolute_url(), "/syspanel/instances/")
  
      def test_index_url_name(self):
          syspanel = horizon.get_dashboard("syspanel")
          instances = syspanel.get_panel("instances")
          instances.index_url_name = "does_not_exist"
          with self.assertRaises(urlresolvers.NoReverseMatch):
              instances.get_absolute_url()
          instances.index_url_name = "index"
          self.assertEqual(instances.get_absolute_url(), "/syspanel/instances/")
  
      def test_lazy_urls(self):
          urlpatterns = horizon.urls[0]
          self.assertTrue(isinstance(urlpatterns, base.LazyURLPattern))
          # The following two methods simply should not raise any exceptions
          iter(urlpatterns)
          reversed(urlpatterns)
  
      def test_horizon_test_isolation_1(self):
          """ Isolation Test Part 1: sets a value. """
          syspanel = horizon.get_dashboard("syspanel")
          syspanel.evil = True
  
      def test_horizon_test_isolation_2(self):
          """ Isolation Test Part 2: The value set in part 1 should be gone. """
          syspanel = horizon.get_dashboard("syspanel")
          self.assertFalse(hasattr(syspanel, "evil"))
  
      def test_public(self):
          users.get_user_from_request = self._real_get_user_from_request
          settings = horizon.get_dashboard("settings")
          # Known to have no restrictions on it other than being logged in.
          user_panel = settings.get_panel("user")
          url = user_panel.get_absolute_url()
          # Get a clean, logged out client instance.
          client = Client()
          client.logout()
          resp = client.get(url)
          redirect_url = "?".join([urlresolvers.reverse("horizon:auth_login"),
                                   "next=%s" % url])
          self.assertRedirectsNoFollow(resp, redirect_url)
          # Simulate ajax call
          resp = client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
          # Response should be HTTP 401 with redirect header
          self.assertEquals(resp.status_code, 401)
          self.assertEquals(resp["X-Horizon-Location"],
                            "?".join([urlresolvers.reverse("horizon:auth_login"),
                                      "next=%s" % url]))
  
      def test_required_services(self):
          horizon.register(MyDash)
          MyDash.register(MyPanel)
          dash = horizon.get_dashboard("mydash")
          panel = dash.get_panel('myslug')
          self._reload_urls()
  
          # With the required service, the page returns fine.
          resp = self.client.get(panel.get_absolute_url())
          self.assertEqual(resp.status_code, 200)
  
          # Remove the required service from the service catalog and we
          # should get a 404.
          new_catalog = [service for service in self.request.user.service_catalog
                         if service['type'] != MyPanel.services[0]]
          tenants = self.context['authorized_tenants']
          self.setActiveUser(token=self.token.id,
                             username=self.user.name,
                             tenant_id=self.tenant.id,
                             service_catalog=new_catalog,
                             authorized_tenants=tenants)
          resp = self.client.get(panel.get_absolute_url())
          self.assertEqual(resp.status_code, 404)
  
      def test_required_roles(self):
          syspanel = horizon.get_dashboard("syspanel")
          user_panel = syspanel.get_panel("users")
  
          # Non-admin user
          self.setActiveUser(token=self.token.id,
                             username=self.user.name,
                             tenant_id=self.tenant.id,
                             service_catalog=self.service_catalog,
                             roles=[])
  
          resp = self.client.get(user_panel.get_absolute_url())
          self.assertEqual(resp.status_code, 302)
  
          resp = self.client.get(user_panel.get_absolute_url(),
                                 follow=False,
                                 HTTP_X_REQUESTED_WITH='XMLHttpRequest')
          self.assertEqual(resp.status_code, 401)
  
          self.mox.StubOutWithMock(api, 'flavor_list')
          api.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list())
          api.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list())
          self.mox.ReplayAll()
  
          # Set roles for admin user
          self.setActiveUser(token=self.token.id,
                             username=self.user.name,
                             tenant_id=self.tenant.id,
                             service_catalog=self.request.user.service_catalog,
                             roles=[{'name': 'admin'}])
  
          resp = self.client.get(
                      urlresolvers.reverse('horizon:syspanel:flavors:create'))
          self.assertEqual(resp.status_code, 200)
          self.assertTemplateUsed(resp, "syspanel/flavors/create.html")
  
          # Test modal form
          resp = self.client.get(
                      urlresolvers.reverse('horizon:syspanel:flavors:create'),
                      follow=False,
                      HTTP_X_REQUESTED_WITH='XMLHttpRequest')
          self.assertEqual(resp.status_code, 200)
          self.assertTemplateUsed(resp, "syspanel/flavors/_create.html")
  