Ensures tab data is preloaded. With tests! Fixes bug 964317.

Change-Id: I55ad1e0b9b836793ee2816cec18160b223f80462
This commit is contained in:
Gabriel Hurley 2012-03-24 20:53:28 -07:00
parent 7d3a0f4d15
commit 33a0a2e401
4 changed files with 58 additions and 13 deletions

View File

@ -89,6 +89,7 @@ class TabGroup(html.HTMLElement):
% self.__class__)
self.request = request
self.kwargs = kwargs
self._data = None
tab_instances = []
for tab in self.tabs:
tab_instances.append((tab.slug, tab(self, request)))
@ -105,7 +106,11 @@ class TabGroup(html.HTMLElement):
"""
for tab in self._tabs.values():
if tab.load and not tab.data_loaded:
tab._data = tab.get_context_data(self.request)
try:
tab._data = tab.get_context_data(self.request)
except:
tab._data = False
exceptions.handle(self.request)
def get_id(self):
"""
@ -262,7 +267,7 @@ class Tab(html.HTMLElement):
@property
def data(self):
if not getattr(self, "_data", None):
if getattr(self, "_data", None) is None:
self._data = self.get_context_data(self.request)
return self._data

View File

@ -38,6 +38,8 @@ class TabView(generic.TemplateView):
try:
tab_group = self.get_tabs(self.request, **kwargs)
context["tab_group"] = tab_group
# Make sure our data is pre-loaded to capture errors.
context["tab_group"].load_tab_data()
except:
exceptions.handle(self.request)
return context
@ -111,12 +113,6 @@ class TabbedTableView(tables.MultiTableMixin, TabView):
handled = tab._tables[table_name].maybe_handle()
return handled
def get_context_data(self, **kwargs):
""" Adds the ``tab_group`` variable to the context data. """
context = super(TabbedTableView, self).get_context_data(**kwargs)
context['tab_group'].load_tab_data()
return context
def get(self, request, *args, **kwargs):
self.load_tabs()
# Gather our table instances. It's important that they're the

View File

@ -49,6 +49,12 @@ wsgi.WSGIRequest.__repr__ = lambda self: "<class 'django.http.HttpRequest'>"
class RequestFactoryWithMessages(RequestFactory):
def get(self, *args, **kwargs):
req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
req.session = []
req._messages = default_storage(req)
return req
def post(self, *args, **kwargs):
req = super(RequestFactoryWithMessages, self).post(*args, **kwargs)
req.session = []
@ -173,8 +179,13 @@ class TestCase(django_test.TestCase):
if 'messages' in self.client.cookies:
message_cookie = self.client.cookies['messages'].value
messages = storage._decode(message_cookie)
elif "messages" in response.context:
# Check for messages in the context
elif hasattr(response, "context") and "messages" in response.context:
messages = response.context["messages"]
# Check for messages attached to the request on a TemplateResponse
elif hasattr(response, "_request") and hasattr(response._request,
"_messages"):
messages = response._request._messages._queued_messages
# If we don't have messages and we don't expect messages, we're done.
if not any(kwargs.values()) and not messages:

View File

@ -14,9 +14,12 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from django import http
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import tabs as horizon_tabs
from horizon import test
@ -77,9 +80,19 @@ class TabWithTable(horizon_tabs.TableTab):
return TEST_DATA
class RecoverableErrorTab(horizon_tabs.Tab):
name = _("Recoverable Error Tab")
slug = "recoverable_error_tab"
template_name = "_tab.html"
def get_context_data(self, request):
# Raise a known recoverable error.
raise exceptions.AlreadyExists("Recoverable!", None)
class TableTabGroup(horizon_tabs.TabGroup):
slug = "tab_group"
tabs = (TabWithTable,)
tabs = [TabWithTable]
class TabWithTableView(horizon_tabs.TabbedTableView):
@ -88,9 +101,6 @@ class TabWithTableView(horizon_tabs.TabbedTableView):
class TabTests(test.TestCase):
def setUp(self):
super(TabTests, self).setUp()
def test_tab_group_basics(self):
tg = Group(self.request)
@ -265,3 +275,26 @@ class TabTests(test.TestCase):
res = view(req)
self.assertEqual(res.status_code, 302)
self.assertEqual(res["location"], "/")
# Ensure that lookup errors are raised as such instead of converted
# to TemplateSyntaxErrors.
action_string = "my_table__toggle__2000000000"
req = self.factory.post('/', {'action': action_string})
self.assertRaises(exceptions.Http302, view, req)
class TabExceptionTests(test.TestCase):
def setUp(self):
super(TabExceptionTests, self).setUp()
self._original_tabs = copy.copy(TabWithTableView.tab_group_class.tabs)
TabWithTableView.tab_group_class.tabs.append(RecoverableErrorTab)
def tearDown(self):
super(TabExceptionTests, self).tearDown()
TabWithTableView.tab_group_class.tabs = self._original_tabs
def test_tab_view_exception(self):
view = TabWithTableView.as_view()
req = self.factory.get("/")
res = view(req)
self.assertMessageCount(res, error=1)