launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #10886
[Merge] lp:~gz/launchpad/root_blog_feature_flag_939055 into lp:launchpad
Martin Packman has proposed merging lp:~gz/launchpad/root_blog_feature_flag_939055 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #939055 in Launchpad itself: "front page blog feed updates are done in-line with requests"
https://bugs.launchpad.net/launchpad/+bug/939055
For more details, see:
https://code.launchpad.net/~gz/launchpad/root_blog_feature_flag_939055/+merge/119399
Only display posts from the launchpad blog on the main page when the new app.root_blog.enabled feature is set. The aim is to easy the datacentre migration by having the option of toggling off the lookup when blog.launchpad.net needs to taken down.
This is something of an abuse of the feature flags... feature, but Robert suggested it as the easiest method in the bug.
To prevent gaping whitespace in the left column, the logic for whether or not to display the launchpad introduction is adapted from always being off for logged in users to being on regardless if the blog isn't being shown.
The tests added are not exhaustive as they're expensive at this level, but should cover the details we care about.
= LOC =
I have some credit to burn...
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/app/browser/root.py
lib/lp/app/browser/tests/test_launchpadroot.py
lib/lp/app/templates/root-index.pt
lib/lp/services/features/flags.py
--
https://code.launchpad.net/~gz/launchpad/root_blog_feature_flag_939055/+merge/119399
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gz/launchpad/root_blog_feature_flag_939055 into lp:launchpad.
=== modified file 'lib/lp/app/browser/root.py'
--- lib/lp/app/browser/root.py 2012-03-23 20:56:11 +0000
+++ lib/lp/app/browser/root.py 2012-08-13 17:49:26 +0000
@@ -43,6 +43,7 @@
GoogleResponseError,
ISearchService,
)
+from lp.services.features import getFeatureFlag
from lp.services.propertycache import cachedproperty
from lp.services.statistics.interfaces.statistic import ILaunchpadStatisticSet
from lp.services.timeout import urlfetch
@@ -136,6 +137,11 @@
"""The total blueprint count in all of Launchpad."""
return getUtility(ILaunchpadStatisticSet).value('question_count')
+ @property
+ def show_whatslaunchpad(self):
+ """True if introduction to Launchpad should be displayed."""
+ return self.user is None or not getFeatureFlag("app.root_blog.enabled")
+
def getRecentBlogPosts(self):
"""Return the parsed feed of the most recent blog posts.
=== modified file 'lib/lp/app/browser/tests/test_launchpadroot.py'
--- lib/lp/app/browser/tests/test_launchpadroot.py 2012-06-04 16:13:51 +0000
+++ lib/lp/app/browser/tests/test_launchpadroot.py 2012-08-13 17:49:26 +0000
@@ -16,9 +16,11 @@
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.registry.interfaces.person import IPersonSet
+from lp.services.features.testing import FeatureFixture
from lp.services.webapp.authorization import check_permission
from lp.services.webapp.interfaces import ILaunchpadRoot
from lp.testing import (
+ anonymous_logged_in,
login_person,
TestCaseWithFactory,
)
@@ -138,3 +140,65 @@
logo = markup.find(True, id='launchpad-logo-and-name')
self.assertIsNot(None, logo)
self.assertEqual('/@@/launchpad-logo-and-name.png', logo['src'])
+
+ @staticmethod
+ def _make_blog_post(linkid, title, body, date):
+ return {
+ 'title': title,
+ 'description': body,
+ 'link': "http://blog.invalid/%s" % (linkid,),
+ 'date': date,
+ }
+
+ def test_blog_posts(self):
+ """Posts from the launchpad blog are shown when feature is enabled"""
+ self.useFixture(FeatureFixture({'app.root_blog.enabled': True}))
+ posts = [
+ self._make_blog_post(1, "A post", "Post contents.", "2002"),
+ self._make_blog_post(2, "Another post", "More contents.", "2003"),
+ ]
+ calls = []
+
+ def _get_blog_posts():
+ calls.append('called')
+ return posts
+
+ root = getUtility(ILaunchpadRoot)
+ with anonymous_logged_in() as user:
+ view = create_initialized_view(root, 'index.html', principle=user)
+ view.getRecentBlogPosts = _get_blog_posts
+ result = view()
+ markup = BeautifulSoup(result,
+ parseOnlyThese=SoupStrainer(id='homepage-blogposts'))
+ self.assertEqual(['called'], calls)
+ items = markup.findAll('li', 'news')
+ # Notice about launchpad being opened is always added at the end
+ self.assertEqual(3, len(items))
+ a = items[-1].find("a")
+ self.assertEqual("Launchpad now open source", a.string.strip())
+ for post, item in zip(posts, items):
+ a = item.find("a")
+ self.assertEqual(post['link'], a["href"])
+ self.assertEqual(post['title'], a.string)
+
+ def test_blog_disabled(self):
+ """Launchpad blog not queried for display without feature"""
+ calls = []
+
+ def _get_blog_posts():
+ calls.append('called')
+ return []
+
+ root = getUtility(ILaunchpadRoot)
+ user = self.factory.makePerson()
+ login_person(user)
+ view = create_initialized_view(root, 'index.html', principal=user)
+ view.getRecentBlogPosts = _get_blog_posts
+ markup = BeautifulSoup(
+ view(), parseOnlyThese=SoupStrainer(id='homepage'))
+ self.assertEqual([], calls)
+ self.assertIs(None, markup.find(True, id='homepage-blogposts'))
+ # Even logged in users should get the launchpad intro text in the left
+ # column rather than blank space when the blog is not being displayed.
+ self.assertTrue(view.show_whatslaunchpad)
+ self.assertTrue(markup.find(True, 'homepage-whatslaunchpad'))
=== modified file 'lib/lp/app/templates/root-index.pt'
--- lib/lp/app/templates/root-index.pt 2012-06-11 00:47:38 +0000
+++ lib/lp/app/templates/root-index.pt 2012-08-13 17:49:26 +0000
@@ -67,7 +67,7 @@
<div class="yui-g">
<div class="yui-u first" style="margin-top: 1.5em;">
<div class="homepage-whatslaunchpad"
- tal:condition="not:view/user">
+ tal:condition="view/show_whatslaunchpad">
<h2><span class="launchpad-gold">Launchpad</span> is a software collaboration platform that provides:</h2>
<ul tal:define="apphomes view/apphomes">
<li>
@@ -109,7 +109,8 @@
</div>
</div>
- <div id="homepage-blogposts" class="homepage-portlet">
+ <div id="homepage-blogposts" class="homepage-portlet"
+ tal:condition="features/app.root_blog.enabled">
<h2>Recent Launchpad blog posts</h2>
<ul tal:define="posts view/getRecentBlogPosts">
<li class="news"
=== modified file 'lib/lp/services/features/flags.py'
--- lib/lp/services/features/flags.py 2012-08-10 06:38:56 +0000
+++ lib/lp/services/features/flags.py 2012-08-13 17:49:26 +0000
@@ -287,6 +287,12 @@
'',
'',
''),
+ ('app.root_blog.enabled',
+ 'boolean',
+ 'If true, load posts from the launchpad for display on the root page.',
+ '',
+ '',
+ ''),
])
# The set of all flag names that are documented.
Follow ups