launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #11418
[Merge] lp:~stevenk/launchpad/db-merge-stable-with-feeling into lp:launchpad/db-devel
Steve Kowalik has proposed merging lp:~stevenk/launchpad/db-merge-stable-with-feeling into lp:launchpad/db-devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~stevenk/launchpad/db-merge-stable-with-feeling/+merge/121752
Merge stable r15871.
--
https://code.launchpad.net/~stevenk/launchpad/db-merge-stable-with-feeling/+merge/121752
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/db-merge-stable-with-feeling into lp:launchpad/db-devel.
=== modified file 'lib/lp/app/browser/lazrjs.py'
--- lib/lp/app/browser/lazrjs.py 2012-08-14 01:57:17 +0000
+++ lib/lp/app/browser/lazrjs.py 2012-08-29 05:40:35 +0000
@@ -40,7 +40,6 @@
get_person_picker_entry_metadata,
vocabulary_filters,
)
-from lp.services.features import getFeatureFlag
from lp.services.propertycache import cachedproperty
from lp.services.webapp.interfaces import ILaunchBag
from lp.services.webapp.publisher import canonical_url
@@ -423,9 +422,7 @@
@property
def show_create_team(self):
- return (self._show_create_team
- and getFeatureFlag(
- "disclosure.add-team-person-picker.enabled"))
+ return self._show_create_team
def getConfig(self):
config = super(InlinePersonEditPickerWidget, self).getConfig()
=== modified file 'lib/lp/app/browser/tests/test_inlineeditpickerwidget.py'
--- lib/lp/app/browser/tests/test_inlineeditpickerwidget.py 2012-06-21 06:50:10 +0000
+++ lib/lp/app/browser/tests/test_inlineeditpickerwidget.py 2012-08-29 05:40:35 +0000
@@ -15,7 +15,6 @@
InlineEditPickerWidget,
InlinePersonEditPickerWidget,
)
-from lp.services.features.testing import FeatureFixture
from lp.testing import (
login_person,
TestCaseWithFactory,
@@ -118,18 +117,9 @@
login_person(self.factory.makePerson())
self.assertFalse(widget.config['show_assign_me_button'])
- def test_show_create_team_link_with_feature_flag(self):
- with FeatureFixture(
- {'disclosure.add-team-person-picker.enabled': 'true'}):
- widget = self.getWidget(
- None, vocabulary='ValidPersonOrTeam', required=True,
- show_create_team=True)
- login_person(self.factory.makePerson())
- self.assertTrue(widget.config['show_create_team'])
-
def test_show_create_team_link(self):
widget = self.getWidget(
None, vocabulary='ValidPersonOrTeam', required=True,
show_create_team=True)
login_person(self.factory.makePerson())
- self.assertFalse(widget.config['show_create_team'])
+ self.assertTrue(widget.config['show_create_team'])
=== modified file 'lib/lp/app/browser/tests/test_vocabulary.py'
--- lib/lp/app/browser/tests/test_vocabulary.py 2012-08-13 19:34:10 +0000
+++ lib/lp/app/browser/tests/test_vocabulary.py 2012-08-29 05:40:35 +0000
@@ -135,40 +135,35 @@
self.assertEqual('sprite person', entry.css)
self.assertEqual('sprite new-window', entry.link_css)
- def test_PersonPickerEntrySourceAdapter_enhanced_picker_user(self):
- # The enhanced person picker provides more information for users.
+ def test_PersonPickerEntrySourceAdapter_user(self):
+ # The person picker provides more information for users.
person = self.factory.makePerson(email='snarf@xxxxxx', name='snarf')
creation_date = datetime(
2005, 01, 30, 0, 0, 0, 0, pytz.timezone('UTC'))
removeSecurityProxy(person).datecreated = creation_date
getUtility(IIrcIDSet).new(person, 'eg.dom', 'snarf')
getUtility(IIrcIDSet).new(person, 'ex.dom', 'pting')
- entry = get_picker_entry(
- person, None, enhanced_picker_enabled=True,
- picker_expander_enabled=True)
+ entry = get_picker_entry(person, None, picker_expander_enabled=True)
self.assertEqual('http://launchpad.dev/~snarf', entry.alt_title_link)
self.assertEqual(
['snarf on eg.dom, pting on ex.dom', 'Member since 2005-01-30'],
entry.details)
- def test_PersonPickerEntrySourceAdapter_enhanced_picker_team(self):
- # The enhanced person picker provides more information for teams.
+ def test_PersonPickerEntrySourceAdapter_team(self):
+ # The person picker provides more information for teams.
team = self.factory.makeTeam(email='fnord@xxxxxx', name='fnord')
- entry = get_picker_entry(
- team, None, enhanced_picker_enabled=True,
- picker_expander_enabled=True)
+ entry = get_picker_entry(team, None, picker_expander_enabled=True)
self.assertEqual('http://launchpad.dev/~fnord', entry.alt_title_link)
self.assertEqual(['Team members: 1'], entry.details)
- def test_PersonPickerEntryAdapter_enhanced_picker_enabled_badges(self):
- # The enhanced person picker provides affiliation information.
+ def test_PersonPickerEntryAdapter_badges(self):
+ # The person picker provides affiliation information.
person = self.factory.makePerson(email='snarf@xxxxxx', name='snarf')
project = self.factory.makeProduct(
name='fnord', owner=person, bug_supervisor=person)
bugtask = self.factory.makeBugTask(target=project)
entry = get_picker_entry(
- person, bugtask, enhanced_picker_enabled=True,
- picker_expander_enabled=True,
+ person, bugtask, picker_expander_enabled=True,
personpicker_affiliation_enabled=True)
self.assertEqual(3, len(entry.badges))
self.assertEqual('/@@/product-badge', entry.badges[0]['url'])
@@ -182,13 +177,12 @@
self.assertEqual('bug supervisor', entry.badges[2]['role'])
def test_PersonPickerEntryAdapter_badges_without_IHasAffiliation(self):
- # The enhanced person picker handles objects that do not support
+ # The person picker handles objects that do not support
# IHasAffilliation.
person = self.factory.makePerson(email='snarf@xxxxxx', name='snarf')
thing = object()
entry = get_picker_entry(
- person, thing, enhanced_picker_enabled=True,
- picker_expander_enabled=True,
+ person, thing, picker_expander_enabled=True,
personpicker_affiliation_enabled=True)
self.assertIsNot(None, entry)
=== modified file 'lib/lp/app/javascript/picker/picker_patcher.js'
--- lib/lp/app/javascript/picker/picker_patcher.js 2012-07-07 14:00:30 +0000
+++ lib/lp/app/javascript/picker/picker_patcher.js 2012-08-29 05:40:35 +0000
@@ -25,19 +25,14 @@
return;
}
var picker_span = show_widget_node.get('parentNode');
- if (config.enhanced_picker) {
- var new_node = Y.Node.create('<span>(<a href="#"></a>)</span>');
- show_widget_node = new_node.one('a');
- show_widget_node
- .set('id', show_widget_id)
- .addClass('js-action')
- .set('text', 'Choose\u2026');
- picker_span.empty();
- picker_span.appendChild(new_node);
- } else {
- show_widget_node.set('text', 'Choose\u2026');
- show_widget_node.addClass('js-action');
- }
+ var new_node = Y.Node.create('<span>(<a href="#"></a>)</span>');
+ show_widget_node = new_node.one('a');
+ show_widget_node
+ .set('id', show_widget_id)
+ .addClass('js-action')
+ .set('text', 'Choose\u2026');
+ picker_span.empty();
+ picker_span.appendChild(new_node);
picker_span.removeClass('hidden');
show_widget_node.on('click', function (e) {
if (picker === null) {
=== modified file 'lib/lp/app/widgets/popup.py'
--- lib/lp/app/widgets/popup.py 2012-07-07 14:00:30 +0000
+++ lib/lp/app/widgets/popup.py 2012-08-29 05:40:35 +0000
@@ -23,7 +23,6 @@
get_person_picker_entry_metadata,
vocabulary_filters,
)
-from lp.services.features import getFeatureFlag
from lp.services.propertycache import cachedproperty
from lp.services.webapp import canonical_url
@@ -58,12 +57,6 @@
# Defaults to self.vocabulary.displayname.
header = None
- @property
- def enhanced_picker(self):
- flag = getFeatureFlag(
- "disclosure.add-team-person-picker.enabled")
- return flag and self.show_create_team_link
-
@cachedproperty
def matches(self):
"""Return a list of matches (as ITokenizedTerm) to whatever the
@@ -152,8 +145,7 @@
vocabulary_filters=self.vocabulary_filters,
input_element=self.input_id,
show_widget_id=self.show_widget_id,
- enhanced_picker=self.enhanced_picker,
- show_create_team=self.enhanced_picker)
+ show_create_team=self.show_create_team_link)
@property
def json_config(self):
=== modified file 'lib/lp/app/widgets/tests/test_popup.py'
--- lib/lp/app/widgets/tests/test_popup.py 2012-06-28 01:27:06 +0000
+++ lib/lp/app/widgets/tests/test_popup.py 2012-08-29 05:40:35 +0000
@@ -13,7 +13,6 @@
PersonPickerWidget,
VocabularyPickerWidget,
)
-from lp.services.features.testing import FeatureFixture
from lp.services.webapp.servers import LaunchpadTestRequest
from lp.testing import TestCaseWithFactory
from lp.testing.layers import DatabaseFunctionalLayer
@@ -170,24 +169,14 @@
self.assertFalse(person_picker_widget.config['show_remove_button'])
def test_create_team_link(self):
- # The person picker widget shows a create team link if the feature flag
- # is on.
+ # The person picker widget shows a create team link.
field = ITest['test_valid.item']
bound_field = field.bind(self.context)
- with FeatureFixture(
- {'disclosure.add-team-person-picker.enabled': 'true'}):
- picker_widget = PersonPickerWidget(
- bound_field, self.vocabulary, self.request)
- picker_widget.show_create_team_link = True
- self.assertTrue(picker_widget.config['show_create_team'])
- self.assertTrue(picker_widget.config['enhanced_picker'])
-
picker_widget = PersonPickerWidget(
bound_field, self.vocabulary, self.request)
picker_widget.show_create_team_link = True
- self.assertFalse(picker_widget.config['show_create_team'])
- self.assertFalse(picker_widget.config['enhanced_picker'])
+ self.assertTrue(picker_widget.config['show_create_team'])
def test_widget_personvalue_meta(self):
# The person picker has the correct meta value for a person value.
=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py 2012-08-24 12:49:00 +0000
+++ lib/lp/bugs/browser/bug.py 2012-08-29 05:40:35 +0000
@@ -2,7 +2,6 @@
# GNU Affero General Public License version 3 (see the file LICENSE).
"""IBug related view classes."""
-from lp.app.interfaces.services import IService
__metaclass__ = type
@@ -72,6 +71,7 @@
LaunchpadFormView,
)
from lp.app.errors import NotFoundError
+from lp.app.interfaces.services import IService
from lp.app.widgets.itemswidgets import LaunchpadRadioWidgetWithDescription
from lp.app.widgets.product import GhostCheckBoxWidget
from lp.app.widgets.project import ProjectScopeWidget
@@ -881,6 +881,7 @@
if self.request.is_ajax:
validate_change = data.get('validate_change', False)
if (validate_change and
+ information_type in PRIVATE_INFORMATION_TYPES and
self._bug_will_be_invisible(information_type)):
self.request.response.setStatus(400, "Bug Visibility")
return ''
=== modified file 'lib/lp/bugs/browser/tests/test_bug_views.py'
--- lib/lp/bugs/browser/tests/test_bug_views.py 2012-08-24 12:49:00 +0000
+++ lib/lp/bugs/browser/tests/test_bug_views.py 2012-08-29 05:40:35 +0000
@@ -97,6 +97,7 @@
# We expect that only the Also Affects Project link is disallowed.
distro = self.factory.makeDistribution()
owner = self.factory.makePerson()
+ self.factory.makeAccessPolicy(pillar=distro)
bug = self.factory.makeBug(
target=distro,
information_type=InformationType.PROPRIETARY, owner=owner)
@@ -402,6 +403,7 @@
# bug will become invisible but and no visibility check is performed.
product = self.factory.makeProduct(
bug_sharing_policy=BugSharingPolicy.PUBLIC_OR_PROPRIETARY)
+ self.factory.makeAccessPolicy(pillar=product)
bug = self.factory.makeBug(target=product)
self._assert_secrecy_view_ajax_render(bug, 'PROPRIETARY', False)
=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
--- lib/lp/bugs/browser/tests/test_bugtask.py 2012-08-21 20:41:05 +0000
+++ lib/lp/bugs/browser/tests/test_bugtask.py 2012-08-29 05:40:35 +0000
@@ -140,12 +140,12 @@
self.getUserBrowser(url, person_no_teams)
# This may seem large: it is; there is easily another 30% fat in
# there.
- # If this test is run in isolation, the query count is 89.
+ # If this test is run in isolation, the query count is 94.
# Other tests in this TestCase could cache the
# "SELECT id, product, project, distribution FROM PillarName ..."
# query by previously browsing the task url, in which case the
# query count is decreased by one.
- self.assertThat(recorder, HasQueryCount(LessThan(94)))
+ self.assertThat(recorder, HasQueryCount(LessThan(95)))
count_with_no_teams = recorder.count
# count with many teams
self.invalidate_caches(task)
@@ -1120,6 +1120,7 @@
# could affect another package.
distro = self.factory.makeDistribution()
owner = self.factory.makePerson()
+ self.factory.makeAccessPolicy(pillar=distro)
bug = self.factory.makeBug(
target=distro, owner=owner,
information_type=InformationType.PROPRIETARY)
@@ -1140,6 +1141,7 @@
sp = self.factory.makeSourcePackage(
sourcepackagename=sp_name, distroseries=distroseries)
owner = self.factory.makePerson()
+ self.factory.makeAccessPolicy(pillar=distro)
bug = self.factory.makeBug(
target=sp.distribution_sourcepackage, owner=owner,
information_type=InformationType.PROPRIETARY)
=== modified file 'lib/lp/bugs/doc/bug.txt'
--- lib/lp/bugs/doc/bug.txt 2012-08-08 11:48:29 +0000
+++ lib/lp/bugs/doc/bug.txt 2012-08-29 05:40:35 +0000
@@ -662,6 +662,7 @@
... comment="a description of the bug",
... owner=current_user())
>>> private_bug = firefox.createBug(params)
+ >>> ignored = factory.makeAccessPolicy(pillar=firefox)
>>> private_bug.transitionToInformationType(
... InformationType.PROPRIETARY, current_user())
True
@@ -730,6 +731,7 @@
We cannot add distro series or source package tasks for different distros.
>>> private_bug = tubuntu.createBug(params)
+ >>> ignored = factory.makeAccessPolicy(pillar=tubuntu)
>>> private_bug.transitionToInformationType(
... InformationType.PROPRIETARY, current_user())
True
=== modified file 'lib/lp/bugs/doc/bugsubscription.txt'
--- lib/lp/bugs/doc/bugsubscription.txt 2012-08-22 23:02:40 +0000
+++ lib/lp/bugs/doc/bugsubscription.txt 2012-08-29 05:40:35 +0000
@@ -364,6 +364,7 @@
>>> print_displayname(linux_source_bug.getDirectSubscribers())
Foo Bar
+ Mark Shuttleworth
Robert Collins
Direct subscriptions always take precedence over indirect subscriptions.
@@ -375,6 +376,7 @@
>>> print_displayname(linux_source_bug.getDirectSubscribers())
Foo Bar
+ Mark Shuttleworth
Robert Collins
>>> print_displayname(linux_source_bug.getIndirectSubscribers())
@@ -398,6 +400,7 @@
>>> addresses = recipients.getEmails()
>>> [(address, recipients.getReason(address)[1]) for address in addresses]
[('foo.bar@xxxxxxxxxxxxx', 'Subscriber'),
+ ('mark@xxxxxxxxxxx', 'Subscriber'),
('no-priv@xxxxxxxxxxxxx', u'Subscriber (linux-source-2.6.15 in Ubuntu)'),
('robertc@xxxxxxxxxxxxxxxxx', 'Subscriber'),
('test@xxxxxxxxxxxxx', 'Assignee')]
@@ -411,6 +414,7 @@
>>> addresses = recipients.getEmails()
>>> [(address, recipients.getReason(address)[1]) for address in addresses]
[('foo.bar@xxxxxxxxxxxxx', 'Subscriber'),
+ ('mark@xxxxxxxxxxx', 'Subscriber'),
('robertc@xxxxxxxxxxxxxxxxx', 'Subscriber'),
('test@xxxxxxxxxxxxx', 'Assignee')]
@@ -424,6 +428,7 @@
>>> addresses = recipients.getEmails()
>>> [(address, recipients.getReason(address)[1]) for address in addresses]
[('foo.bar@xxxxxxxxxxxxx', 'Subscriber'),
+ ('mark@xxxxxxxxxxx', 'Subscriber'),
('robertc@xxxxxxxxxxxxxxxxx', 'Subscriber'),
('test@xxxxxxxxxxxxx', 'Assignee')]
@@ -435,6 +440,7 @@
>>> addresses = recipients.getEmails()
>>> [(address, recipients.getReason(address)[1]) for address in addresses]
[('foo.bar@xxxxxxxxxxxxx', 'Subscriber'),
+ ('mark@xxxxxxxxxxx', 'Subscriber'),
('no-priv@xxxxxxxxxxxxx', u'Subscriber (linux-source-2.6.15 in Ubuntu)'),
('robertc@xxxxxxxxxxxxxxxxx', 'Subscriber'),
('test@xxxxxxxxxxxxx', 'Assignee')]
=== modified file 'lib/lp/bugs/javascript/filebug.js'
--- lib/lp/bugs/javascript/filebug.js 2012-08-21 13:27:00 +0000
+++ lib/lp/bugs/javascript/filebug.js 2012-08-29 05:40:35 +0000
@@ -69,7 +69,7 @@
Y.Array.forEach(LP.cache.information_type_data, function(item) {
info_type_descriptions[item.value] = item.name;
});
- var text_template = "This report has {info_type} information." +
+ var text_template = "This report contains {info_type} information." +
" You can change the information type later.";
value = info_type_descriptions[value];
return Y.Lang.substitute(text_template, {'info_type': value});
=== modified file 'lib/lp/bugs/javascript/tests/test_filebug.js'
--- lib/lp/bugs/javascript/tests/test_filebug.js 2012-07-19 03:18:37 +0000
+++ lib/lp/bugs/javascript/tests/test_filebug.js 2012-08-29 05:40:35 +0000
@@ -91,7 +91,7 @@
Y.Assert.isNull(banner_hidden);
var banner_text = Y.one('.banner-text').get('text');
Y.Assert.areEqual(
- 'This report has Private Security information. ' +
+ 'This report contains Private Security information. ' +
'You can change the information type later.', banner_text);
},
@@ -281,7 +281,7 @@
Y.Assert.isNull(banner_hidden);
var banner_text = Y.one('.banner-text').get('text');
Y.Assert.areEqual(
- 'This report has Private information. ' +
+ 'This report contains Private information. ' +
'You can change the information type later.', banner_text);
},
=== modified file 'lib/lp/bugs/mail/tests/test_commands.py'
--- lib/lp/bugs/mail/tests/test_commands.py 2012-08-21 19:19:32 +0000
+++ lib/lp/bugs/mail/tests/test_commands.py 2012-08-29 05:40:35 +0000
@@ -287,6 +287,7 @@
# Test that attempts to invalidly add a new bug task results in the
# expected error message.
product = self.factory.makeProduct()
+ self.factory.makeAccessPolicy(pillar=product)
bug = self.factory.makeBug(
target=product, information_type=InformationType.PROPRIETARY)
self.factory.makeProduct(name='fnord')
=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py 2012-08-23 04:20:48 +0000
+++ lib/lp/bugs/model/bug.py 2012-08-29 05:40:35 +0000
@@ -200,7 +200,6 @@
sqlvalues,
)
from lp.services.database.stormbase import StormBase
-from lp.services.features import getFeatureFlag
from lp.services.fields import DuplicateBug
from lp.services.helpers import shortlist
from lp.services.librarian.interfaces import ILibraryFileAliasSet
@@ -1766,18 +1765,10 @@
if pillar.driver in subscribers and pillar != ubuntu:
required_subscribers.add(pillar.driver)
service = getUtility(IService, 'sharing')
- subscribers_to_remove = set(service.getPeopleWithoutAccess(
- self, subscribers)).difference(required_subscribers)
if len(required_subscribers):
service.ensureAccessGrants(
required_subscribers, who, bugs=[self],
ignore_permissions=True)
- # There is a job to do the unsubscribe, but it's behind a
- # flag. If that flag is not set, do it manually.
- if len(subscribers_to_remove) and not bool(
- getFeatureFlag('disclosure.unsubscribe_jobs.enabled')):
- for s in subscribers_to_remove:
- self.unsubscribe(s, who, ignore_permissions=True)
# Add the required subscribers, but not if they are all already
# subscribed via a team.
@@ -1788,13 +1779,10 @@
self.updateHeat()
- flag = 'disclosure.unsubscribe_jobs.enabled'
- if bool(getFeatureFlag(flag)):
- # As a result of the transition, some subscribers may no longer
- # have access to the bug. We need to run a job to remove any such
- # subscriptions.
- getUtility(IRemoveArtifactSubscriptionsJobSource).create(
- who, [self])
+ # As a result of the transition, some subscribers may no longer
+ # have access to the bug. We need to run a job to remove any such
+ # subscriptions.
+ getUtility(IRemoveArtifactSubscriptionsJobSource).create(who, [self])
return True
=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py 2012-08-24 01:17:35 +0000
+++ lib/lp/bugs/model/bugtask.py 2012-08-29 05:40:35 +0000
@@ -141,7 +141,6 @@
SQLBase,
sqlvalues,
)
-from lp.services.features import getFeatureFlag
from lp.services.helpers import shortlist
from lp.services.propertycache import get_property_cache
from lp.services.searchbuilder import any
@@ -1140,13 +1139,11 @@
self.maybeConfirm()
# END TEMPORARY BIT FOR BUGTASK AUTOCONFIRM FEATURE FLAG.
- flag = 'disclosure.unsubscribe_jobs.enabled'
- if bool(getFeatureFlag(flag)):
- # As a result of the transition, some subscribers may no longer
- # have access to the parent bug. We need to run a job to remove any
- # such subscriptions.
- getUtility(IRemoveArtifactSubscriptionsJobSource).create(
- user, [self.bug], pillar=target_before_change.pillar)
+ # As a result of the transition, some subscribers may no longer
+ # have access to the parent bug. We need to run a job to remove any
+ # such subscriptions.
+ getUtility(IRemoveArtifactSubscriptionsJobSource).create(
+ user, [self.bug], pillar=target_before_change.pillar)
def updateTargetNameCache(self, newtarget=None):
"""See `IBugTask`."""
=== modified file 'lib/lp/bugs/model/tests/test_bug.py'
--- lib/lp/bugs/model/tests/test_bug.py 2012-08-23 04:20:48 +0000
+++ lib/lp/bugs/model/tests/test_bug.py 2012-08-29 05:40:35 +0000
@@ -639,7 +639,7 @@
who = self.factory.makePerson(name='who')
bug.transitionToInformationType(
InformationType.PRIVATESECURITY, who=who)
- subscribers = bug.getDirectSubscribers()
+ subscribers = bug.getDirectSubscribers(filter_visible=True)
expected_subscribers = set((
default_bugtask.pillar.driver, bug_owner, who))
self.assertContentEqual(expected_subscribers, subscribers)
@@ -662,7 +662,7 @@
bug.subscribe(subscriber, bug_owner)
who = self.factory.makePerson(name='who')
bug.transitionToInformationType(InformationType.USERDATA, who)
- subscribers = bug.getDirectSubscribers()
+ subscribers = bug.getDirectSubscribers(filter_visible=True)
expected_subscribers = set((
default_bugtask.pillar.bug_supervisor,
default_bugtask.pillar.driver,
=== modified file 'lib/lp/bugs/model/tests/test_bugsummary.py'
--- lib/lp/bugs/model/tests/test_bugsummary.py 2012-08-08 11:48:29 +0000
+++ lib/lp/bugs/model/tests/test_bugsummary.py 2012-08-29 05:40:35 +0000
@@ -28,7 +28,6 @@
SharingPermission,
)
from lp.services.database.lpstorm import IMasterStore
-from lp.services.features.testing import FeatureFixture
from lp.testing import TestCaseWithFactory
from lp.testing.dbuser import switch_dbuser
from lp.testing.layers import LaunchpadZopelessLayer
@@ -192,11 +191,9 @@
person_b = self.factory.makePerson()
person_c = self.factory.makePerson()
product = self.factory.makeProduct()
- with FeatureFixture(
- {'disclosure.enhanced_sharing.writable': 'true'}):
- getUtility(IService, 'sharing').sharePillarInformation(
- product, person_c, product.owner,
- {InformationType.USERDATA: SharingPermission.ALL})
+ getUtility(IService, 'sharing').sharePillarInformation(
+ product, person_c, product.owner,
+ {InformationType.USERDATA: SharingPermission.ALL})
bug = self.factory.makeBug(target=product, owner=person_b)
bug.subscribe(person=person_a, subscribed_by=person_a)
=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py 2012-08-21 15:13:25 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py 2012-08-29 05:40:35 +0000
@@ -2678,7 +2678,6 @@
def setUp(self):
self.useFixture(FeatureFixture({
- 'disclosure.unsubscribe_jobs.enabled': 'true',
'jobs.celery.enabled_classes': 'RemoveArtifactSubscriptionsJob',
}))
super(TestTransitionsRemovesSubscribersJob, self).setUp()
@@ -2856,6 +2855,7 @@
if not self.multi_tenant_test_one_task_only:
self.factory.makeBugTask(bug=bug)
p = self.factory.makeProduct()
+ self.factory.makeAccessPolicy(pillar=d)
with person_logged_in(bug.owner):
bug.transitionToInformationType(
InformationType.PROPRIETARY, bug.owner)
@@ -2877,6 +2877,7 @@
bug = self.factory.makeBug(target=p1)
if not self.multi_tenant_test_one_task_only:
self.factory.makeBugTask(bug=bug)
+ self.factory.makeAccessPolicy(pillar=p1)
with person_logged_in(bug.owner):
bug.transitionToInformationType(
InformationType.PROPRIETARY, bug.owner)
@@ -2905,6 +2906,7 @@
bug = self.factory.makeBug(target=p1)
if not self.multi_tenant_test_one_task_only:
self.factory.makeBugTask(bug=bug)
+ self.factory.makeAccessPolicy(pillar=p1)
with person_logged_in(bug.owner):
bug.transitionToInformationType(
InformationType.PROPRIETARY, bug.owner)
@@ -2927,6 +2929,7 @@
bug = self.factory.makeBug(target=d1)
if not self.multi_tenant_test_one_task_only:
self.factory.makeBugTask(bug=bug)
+ self.factory.makeAccessPolicy(pillar=d1)
with person_logged_in(bug.owner):
bug.transitionToInformationType(
InformationType.PROPRIETARY, bug.owner)
=== modified file 'lib/lp/bugs/model/tests/test_bugtasksearch.py'
--- lib/lp/bugs/model/tests/test_bugtasksearch.py 2012-08-16 05:18:54 +0000
+++ lib/lp/bugs/model/tests/test_bugtasksearch.py 2012-08-29 05:40:35 +0000
@@ -67,7 +67,6 @@
from lp.registry.model.person import Person
from lp.services.database.lpstorm import IStore
from lp.services.database.sqlbase import convert_storm_clause_to_string
-from lp.services.features.testing import FeatureFixture
from lp.services.searchbuilder import (
all,
any,
@@ -2410,8 +2409,6 @@
# People and teams with AccessPolicyGrants can see the bug.
self.makePrivacyScenario()
- self.useFixture(FeatureFixture(
- {'disclosure.enhanced_sharing.writable': 'true'}))
with admin_logged_in():
for princ in (self.grantee_team, self.grantee_person):
getUtility(IService, 'sharing').sharePillarInformation(
=== modified file 'lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt'
--- lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt 2012-07-10 08:12:53 +0000
+++ lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt 2012-08-29 05:40:35 +0000
@@ -215,6 +215,7 @@
>>> login("foo.bar@xxxxxxxxxxxxx")
>>> productset = getUtility(IProductSet)
>>> firefox = productset.get(4)
+ >>> ignored = factory.makeAccessPolicy(pillar=firefox)
>>> params = CreateBugParams(
... title="a test private bug",
... comment="a description of the bug",
=== modified file 'lib/lp/code/browser/tests/test_branch.py'
--- lib/lp/code/browser/tests/test_branch.py 2012-08-22 14:23:12 +0000
+++ lib/lp/code/browser/tests/test_branch.py 2012-08-29 05:40:35 +0000
@@ -1028,8 +1028,10 @@
# We don't force branches with a disallowed type (eg. Proprietary on a
# non-commercial project) to change, so the current type is
# shown.
+ product = self.factory.makeProduct()
+ self.factory.makeAccessPolicy(pillar=product)
branch = self.factory.makeBranch(
- information_type=InformationType.PROPRIETARY)
+ product=product, information_type=InformationType.PROPRIETARY)
self.assertShownTypes(
[InformationType.PUBLIC, InformationType.PROPRIETARY], branch)
=== modified file 'lib/lp/code/model/branch.py'
--- lib/lp/code/model/branch.py 2012-08-07 02:31:56 +0000
+++ lib/lp/code/model/branch.py 2012-08-29 05:40:35 +0000
@@ -171,7 +171,6 @@
ArrayAgg,
ArrayIntersects,
)
-from lp.services.features import getFeatureFlag
from lp.services.helpers import shortlist
from lp.services.job.interfaces.job import JobStatus
from lp.services.job.model.job import Job
@@ -272,13 +271,10 @@
service.ensureAccessGrants(
blind_subscribers, who, branches=[self],
ignore_permissions=True)
- flag = 'disclosure.unsubscribe_jobs.enabled'
- if bool(getFeatureFlag(flag)):
- # As a result of the transition, some subscribers may no longer
- # have access to the branch. We need to run a job to remove any
- # such subscriptions.
- getUtility(IRemoveArtifactSubscriptionsJobSource).create(
- who, [self])
+ # As a result of the transition, some subscribers may no longer
+ # have access to the branch. We need to run a job to remove any
+ # such subscriptions.
+ getUtility(IRemoveArtifactSubscriptionsJobSource).create(who, [self])
registrant = ForeignKey(
dbName='registrant', foreignKey='Person',
=== modified file 'lib/lp/code/model/tests/test_branchjob.py'
--- lib/lp/code/model/tests/test_branchjob.py 2012-06-28 01:14:33 +0000
+++ lib/lp/code/model/tests/test_branchjob.py 2012-08-29 05:40:35 +0000
@@ -65,6 +65,7 @@
from lp.code.model.revision import RevisionSet
from lp.code.model.tests.test_branch import create_knit
from lp.codehosting.vfs import branch_id_to_path
+from lp.registry.enums import InformationType
from lp.scripts.helpers import TransactionFreeOperation
from lp.services.config import config
from lp.services.database.constants import UTC_NOW
@@ -173,6 +174,23 @@
self.assertEqual(db_branch.revision_count, 5)
+ def test_run_with_private_linked_bug(self):
+ """Ensure the job scans a branch with a private bug in the revprops."""
+ self.useBzrBranches(direct_database=True)
+ db_branch, bzr_tree = self.create_branch_and_tree()
+ product = self.factory.makeProduct()
+ private_bug = self.factory.makeBug(
+ target=product, information_type=InformationType.USERDATA)
+ bug_line = 'https://launchpad.net/bugs/%s fixed' % private_bug.id
+ with override_environ(BZR_EMAIL='me@xxxxxxxxxxx'):
+ bzr_tree.commit(
+ 'First commit', rev_id='rev1', revprops={'bugs': bug_line})
+ job = BranchScanJob.create(db_branch)
+ with dbuser(config.branchscanner.dbuser):
+ job.run()
+ self.assertEqual(db_branch.revision_count, 1)
+ self.assertTrue(private_bug.hasBranch(db_branch))
+
class TestBranchUpgradeJob(TestCaseWithFactory):
"""Tests for `BranchUpgradeJob`."""
=== modified file 'lib/lp/code/model/tests/test_branchnamespace.py'
--- lib/lp/code/model/tests/test_branchnamespace.py 2012-08-22 14:23:12 +0000
+++ lib/lp/code/model/tests/test_branchnamespace.py 2012-08-29 05:40:35 +0000
@@ -57,7 +57,6 @@
)
from lp.registry.interfaces.product import NoSuchProduct
from lp.registry.model.sourcepackage import SourcePackage
-from lp.services.features.testing import FeatureFixture
from lp.testing import (
person_logged_in,
TestCaseWithFactory,
@@ -458,11 +457,6 @@
layer = DatabaseFunctionalLayer
- def setUp(self):
- super(TestProductNamespacePrivacyWithInformationType, self).setUp()
- self.useFixture(FeatureFixture(
- {'disclosure.enhanced_sharing.writable': 'true'}))
-
def makeProductNamespace(self, sharing_policy, person=None):
if person is None:
person = self.factory.makePerson()
=== modified file 'lib/lp/registry/browser/distribution.py'
--- lib/lp/registry/browser/distribution.py 2012-08-21 00:34:02 +0000
+++ lib/lp/registry/browser/distribution.py 2012-08-29 05:40:35 +0000
@@ -108,7 +108,6 @@
)
from lp.registry.interfaces.series import SeriesStatus
from lp.services.database.decoratedresultset import DecoratedResultSet
-from lp.services.features import getFeatureFlag
from lp.services.feeds.browser import FeedsMixin
from lp.services.geoip.helpers import (
ipaddress_from_request,
@@ -313,12 +312,7 @@
@enabled_with_permission('launchpad.Driver')
def sharing(self):
- text = 'Sharing'
- enabled_readonly_flag = 'disclosure.enhanced_sharing.enabled'
- enabled_writable_flag = 'disclosure.enhanced_sharing.writable'
- enabled = (bool(getFeatureFlag(enabled_readonly_flag))
- or bool(getFeatureFlag(enabled_writable_flag)))
- return Link('+sharing', text, icon='edit', enabled=enabled)
+ return Link('+sharing', 'Sharing', icon='edit')
@cachedproperty
def links(self):
=== modified file 'lib/lp/registry/browser/pillar.py'
--- lib/lp/registry/browser/pillar.py 2012-08-23 04:42:37 +0000
+++ lib/lp/registry/browser/pillar.py 2012-08-29 05:40:35 +0000
@@ -31,7 +31,6 @@
getVocabularyRegistry,
SimpleVocabulary,
)
-from zope.security.interfaces import Unauthorized
from zope.traversing.browser.absoluteurl import absoluteURL
from lp.app.browser.launchpad import iter_view_registrations
@@ -60,9 +59,7 @@
from lp.registry.interfaces.projectgroup import IProjectGroup
from lp.registry.model.pillar import PillarPerson
from lp.services.config import config
-from lp.services.features import getFeatureFlag
from lp.services.propertycache import cachedproperty
-from lp.services.webapp.authorization import check_permission
from lp.services.webapp.batching import (
BatchNavigator,
StormRangeFactory,
@@ -278,11 +275,6 @@
sharing_vocabulary_name = 'NewPillarGrantee'
- related_features = (
- 'disclosure.enhanced_sharing.enabled',
- 'disclosure.enhanced_sharing.writable',
- )
-
_batch_navigator = None
def _getSharingService(self):
@@ -348,16 +340,7 @@
def initialize(self):
super(PillarSharingView, self).initialize()
- enabled_readonly_flag = 'disclosure.enhanced_sharing.enabled'
- enabled_writable_flag = (
- 'disclosure.enhanced_sharing.writable')
- enabled = bool(getFeatureFlag(enabled_readonly_flag))
- write_flag_enabled = bool(getFeatureFlag(enabled_writable_flag))
- if not enabled and not write_flag_enabled:
- raise Unauthorized("This feature is not yet available.")
cache = IJSONRequestCache(self.request)
- cache.objects['sharing_write_enabled'] = (write_flag_enabled
- and check_permission('launchpad.Edit', self.context))
cache.objects['information_types'] = self.information_types
cache.objects['sharing_permissions'] = self.sharing_permissions
cache.objects['bug_sharing_policies'] = self.bug_sharing_policies
@@ -402,11 +385,6 @@
label = "Information shared with person or team"
def initialize(self):
- enabled_flag = 'disclosure.enhanced_sharing_details.enabled'
- enabled = bool(getFeatureFlag(enabled_flag))
- if not enabled:
- raise Unauthorized("This feature is not yet available.")
-
self.pillar = self.context.pillar
self.person = self.context.person
@@ -431,11 +409,6 @@
cache.objects['pillar'] = pillar_data
cache.objects['bugs'] = bug_data
cache.objects['branches'] = branch_data
- enabled_writable_flag = (
- 'disclosure.enhanced_sharing.writable')
- write_flag_enabled = bool(getFeatureFlag(enabled_writable_flag))
- cache.objects['sharing_write_enabled'] = (write_flag_enabled
- and check_permission('launchpad.Edit', self.pillar))
def _loadSharedArtifacts(self):
# As a concrete can by linked via more than one policy, we use sets to
=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py 2012-08-23 04:42:37 +0000
+++ lib/lp/registry/browser/product.py 2012-08-29 05:40:35 +0000
@@ -171,7 +171,6 @@
from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
from lp.services.config import config
from lp.services.database.decoratedresultset import DecoratedResultSet
-from lp.services.features import getFeatureFlag
from lp.services.feeds.browser import FeedsMixin
from lp.services.fields import (
PillarAliases,
@@ -500,12 +499,7 @@
@enabled_with_permission('launchpad.Driver')
def sharing(self):
- text = 'Sharing'
- enabled_readonly_flag = 'disclosure.enhanced_sharing.enabled'
- enabled_writable_flag = 'disclosure.enhanced_sharing.writable'
- enabled = (bool(getFeatureFlag(enabled_readonly_flag))
- or bool(getFeatureFlag(enabled_writable_flag)))
- return Link('+sharing', text, icon='edit', enabled=enabled)
+ return Link('+sharing', 'Sharing', icon='edit')
class IProductEditMenu(Interface):
=== modified file 'lib/lp/registry/browser/tests/test_pillar_sharing.py'
--- lib/lp/registry/browser/tests/test_pillar_sharing.py 2012-08-14 04:48:36 +0000
+++ lib/lp/registry/browser/tests/test_pillar_sharing.py 2012-08-29 05:40:35 +0000
@@ -17,7 +17,6 @@
Raises,
)
from zope.component import getUtility
-from zope.security.interfaces import Unauthorized
from zope.traversing.browser.absoluteurl import absoluteURL
from lp.app.interfaces.services import IService
@@ -30,7 +29,6 @@
from lp.registry.model.pillar import PillarPerson
from lp.services.config import config
from lp.services.database.lpstorm import IStore
-from lp.services.features.testing import FeatureFixture
from lp.services.webapp.interfaces import StormRangeFactoryError
from lp.services.webapp.publisher import canonical_url
from lp.testing import (
@@ -49,14 +47,6 @@
)
-DETAILS_ENABLED_FLAG = {'disclosure.enhanced_sharing_details.enabled': 'true'}
-DETAILS_WRITE_FLAG = {
- 'disclosure.enhanced_sharing_details.enabled': 'true',
- 'disclosure.enhanced_sharing.writable': 'true'}
-ENABLED_FLAG = {'disclosure.enhanced_sharing.enabled': 'true'}
-WRITE_FLAG = {'disclosure.enhanced_sharing.writable': 'true'}
-
-
class SharingBaseTestCase(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
@@ -146,124 +136,94 @@
# There are bugs in the sharingdetails view that not everyone with
# `launchpad.Driver` -- the permission level for the page -- should be
# able to see.
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- pillarperson = self.getPillarPerson(security=True)
- logout()
- login_person(self.driver)
- view = create_initialized_view(pillarperson, '+index')
- # The page loads
- self.assertEqual(pillarperson.person.displayname, view.page_title)
- # The bug, which is not shared with the driver, is not included.
- self.assertEqual(0, view.shared_bugs_count)
+ pillarperson = self.getPillarPerson(security=True)
+ logout()
+ login_person(self.driver)
+ view = create_initialized_view(pillarperson, '+index')
+ # The page loads
+ self.assertEqual(pillarperson.person.displayname, view.page_title)
+ # The bug, which is not shared with the driver, is not included.
+ self.assertEqual(0, view.shared_bugs_count)
def test_view_traverses_plus_sharingdetails(self):
# The traversed url in the app is pillar/+sharing/person
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- # We have to do some fun url hacking to force the traversal a user
- # encounters.
- pillarperson = self.getPillarPerson()
- expected = "Sharing details for %s : Sharing : %s" % (
- pillarperson.person.displayname,
- pillarperson.pillar.displayname)
- url = 'http://launchpad.dev/%s/+sharing/%s' % (
- pillarperson.pillar.name, pillarperson.person.name)
- browser = self.getUserBrowser(user=self.owner, url=url)
- self.assertEqual(expected, browser.title)
+ # We have to do some fun url hacking to force the traversal a user
+ # encounters.
+ pillarperson = self.getPillarPerson()
+ expected = "Sharing details for %s : Sharing : %s" % (
+ pillarperson.person.displayname,
+ pillarperson.pillar.displayname)
+ url = 'http://launchpad.dev/%s/+sharing/%s' % (
+ pillarperson.pillar.name, pillarperson.person.name)
+ browser = self.getUserBrowser(user=self.owner, url=url)
+ self.assertEqual(expected, browser.title)
def test_no_sharing_message(self):
# If there is no sharing between pillar and person, a suitable message
# is displayed.
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- # We have to do some fun url hacking to force the traversal a user
- # encounters.
- pillarperson = PillarPerson(
- self.pillar, self.factory.makePerson())
- url = 'http://launchpad.dev/%s/+sharing/%s' % (
- pillarperson.pillar.name, pillarperson.person.name)
- browser = self.getUserBrowser(user=self.owner, url=url)
- self.assertIn(
- 'There are no shared bugs or branches.',
- browser.contents)
-
- def test_init_without_feature_flag(self):
- # We need a feature flag to enable the view.
- pillarperson = self.getPillarPerson()
- self.assertRaises(
- Unauthorized, create_initialized_view, pillarperson, '+index')
-
- def test_init_with_feature_flag(self):
+ # We have to do some fun url hacking to force the traversal a user
+ # encounters.
+ pillarperson = PillarPerson(
+ self.pillar, self.factory.makePerson())
+ url = 'http://launchpad.dev/%s/+sharing/%s' % (
+ pillarperson.pillar.name, pillarperson.person.name)
+ browser = self.getUserBrowser(user=self.owner, url=url)
+ self.assertIn(
+ 'There are no shared bugs or branches.', browser.contents)
+
+ def test_init_works(self):
# The view works with a feature flag.
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- pillarperson = self.getPillarPerson()
- view = create_initialized_view(pillarperson, '+index')
- self.assertEqual(pillarperson.person.displayname, view.page_title)
- self.assertEqual(1, view.shared_bugs_count)
+ pillarperson = self.getPillarPerson()
+ view = create_initialized_view(pillarperson, '+index')
+ self.assertEqual(pillarperson.person.displayname, view.page_title)
+ self.assertEqual(1, view.shared_bugs_count)
def test_view_data_model(self):
# Test that the json request cache contains the view data model.
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- pillarperson = self.getPillarPerson()
- view = create_initialized_view(pillarperson, '+index')
- bugtask = list(view.bugtasks)[0]
- bug = bugtask.bug
- cache = IJSONRequestCache(view.request)
- request = get_current_web_service_request()
- self.assertEqual({
- 'self_link': absoluteURL(pillarperson.person, request),
- 'displayname': pillarperson.person.displayname
- }, cache.objects.get('grantee'))
- self.assertEqual({
- 'self_link': absoluteURL(pillarperson.pillar, request),
- }, cache.objects.get('pillar'))
- self.assertEqual({
- 'bug_id': bug.id,
- 'bug_summary': bug.title,
- 'bug_importance': bugtask.importance.title.lower(),
- 'information_type': bug.information_type.title,
- 'web_link': canonical_url(
- bugtask, path_only_if_possible=True),
- 'self_link': absoluteURL(bug, request),
- }, cache.objects.get('bugs')[0])
- if self.pillar_type == 'product':
- branch = list(view.branches)[0]
- self.assertEqual({
- 'branch_id': branch.id,
- 'branch_name': branch.unique_name,
- 'information_type': InformationType.USERDATA.title,
- 'web_link': canonical_url(
- branch, path_only_if_possible=True),
- 'self_link': absoluteURL(branch, request),
- }, cache.objects.get('branches')[0])
+ pillarperson = self.getPillarPerson()
+ view = create_initialized_view(pillarperson, '+index')
+ bugtask = list(view.bugtasks)[0]
+ bug = bugtask.bug
+ cache = IJSONRequestCache(view.request)
+ request = get_current_web_service_request()
+ self.assertEqual({
+ 'self_link': absoluteURL(pillarperson.person, request),
+ 'displayname': pillarperson.person.displayname
+ }, cache.objects.get('grantee'))
+ self.assertEqual({
+ 'self_link': absoluteURL(pillarperson.pillar, request),
+ }, cache.objects.get('pillar'))
+ self.assertEqual({
+ 'bug_id': bug.id,
+ 'bug_summary': bug.title,
+ 'bug_importance': bugtask.importance.title.lower(),
+ 'information_type': bug.information_type.title,
+ 'web_link': canonical_url(
+ bugtask, path_only_if_possible=True),
+ 'self_link': absoluteURL(bug, request),
+ }, cache.objects.get('bugs')[0])
+ if self.pillar_type == 'product':
+ branch = list(view.branches)[0]
+ self.assertEqual({
+ 'branch_id': branch.id,
+ 'branch_name': branch.unique_name,
+ 'information_type': InformationType.USERDATA.title,
+ 'web_link': canonical_url(branch, path_only_if_possible=True),
+ 'self_link': absoluteURL(branch, request),
+ }, cache.objects.get('branches')[0])
def test_view_query_count(self):
# Test that the view bulk loads artifacts.
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- person = self.factory.makePerson()
- for x in range(0, 15):
- self.makeArtifactGrantee(person, True, True, False)
- pillarperson = PillarPerson(self.pillar, person)
-
- # Invalidate the Storm cache and check the query count.
- IStore(self.pillar).invalidate()
- with StormStatementRecorder() as recorder:
- create_initialized_view(pillarperson, '+index')
- self.assertThat(recorder, HasQueryCount(LessThan(12)))
-
- def test_view_write_enabled_without_feature_flag(self):
- # Test that sharing_write_enabled is not set without the feature flag.
- with FeatureFixture(DETAILS_ENABLED_FLAG):
- pillarperson = self.getPillarPerson()
- view = create_initialized_view(pillarperson, '+index')
- cache = IJSONRequestCache(view.request)
- self.assertFalse(cache.objects.get('sharing_write_enabled'))
-
- def test_view_write_enabled_with_feature_flag(self):
- # Test that sharing_write_enabled is set when required.
- with FeatureFixture(DETAILS_WRITE_FLAG):
- pillarperson = self.getPillarPerson()
- view = create_initialized_view(pillarperson, '+index')
- cache = IJSONRequestCache(view.request)
- self.assertTrue(cache.objects.get('sharing_write_enabled'))
+ person = self.factory.makePerson()
+ for x in range(0, 15):
+ self.makeArtifactGrantee(person, True, True, False)
+ pillarperson = PillarPerson(self.pillar, person)
+
+ # Invalidate the Storm cache and check the query count.
+ IStore(self.pillar).invalidate()
+ with StormStatementRecorder() as recorder:
+ create_initialized_view(pillarperson, '+index')
+ self.assertThat(recorder, HasQueryCount(LessThan(12)))
class TestProductSharingDetailsView(
@@ -289,132 +249,83 @@
class PillarSharingViewTestMixin:
"""Test the PillarSharingView."""
- def test_init_without_feature_flag(self):
- # We need a feature flag to enable the view.
- self.assertRaises(
- Unauthorized, create_initialized_view, self.pillar, '+sharing')
-
- def test_init_with_feature_flag(self):
- # The view works with a feature flag.
- with FeatureFixture(ENABLED_FLAG):
- view = create_initialized_view(self.pillar, '+sharing')
- self.assertEqual('Sharing', view.page_title)
-
- def test_sharing_menu_without_feature_flag(self):
+ def test_sharing_menu(self):
url = canonical_url(self.pillar)
browser = setupBrowserForUser(user=self.driver)
browser.open(url)
soup = BeautifulSoup(browser.contents)
- sharing_menu = soup.find('a', {'class': 'menu-link-sharing'})
- self.assertIsNone(sharing_menu)
-
- def test_sharing_menu_with_feature_flag(self):
- with FeatureFixture(ENABLED_FLAG):
- url = canonical_url(self.pillar)
- browser = setupBrowserForUser(user=self.driver)
- browser.open(url)
- soup = BeautifulSoup(browser.contents)
- sharing_url = canonical_url(self.pillar, view_name='+sharing')
- sharing_menu = soup.find('a', {'href': sharing_url})
- self.assertIsNotNone(sharing_menu)
+ sharing_url = canonical_url(self.pillar, view_name='+sharing')
+ sharing_menu = soup.find('a', {'href': sharing_url})
+ self.assertIsNotNone(sharing_menu)
def test_picker_config(self):
# Test the config passed to the disclosure sharing picker.
- with FeatureFixture(ENABLED_FLAG):
- view = create_view(self.pillar, name='+sharing')
- picker_config = simplejson.loads(view.json_sharing_picker_config)
- self.assertTrue('vocabulary_filters' in picker_config)
- self.assertEqual(
- 'Share project information',
- picker_config['header'])
- self.assertEqual(
- 'Search for user or exclusive team with whom to share',
- picker_config['steptitle'])
- self.assertEqual(
- 'NewPillarGrantee', picker_config['vocabulary'])
+ view = create_view(self.pillar, name='+sharing')
+ picker_config = simplejson.loads(view.json_sharing_picker_config)
+ self.assertTrue('vocabulary_filters' in picker_config)
+ self.assertEqual('Share project information', picker_config['header'])
+ self.assertEqual(
+ 'Search for user or exclusive team with whom to share',
+ picker_config['steptitle'])
+ self.assertEqual('NewPillarGrantee', picker_config['vocabulary'])
def test_view_data_model(self):
# Test that the json request cache contains the view data model.
- with FeatureFixture(ENABLED_FLAG):
- view = create_initialized_view(self.pillar, name='+sharing')
- cache = IJSONRequestCache(view.request)
- self.assertIsNotNone(cache.objects.get('information_types'))
- self.assertIsNotNone(
- cache.objects.get('branch_sharing_policies'))
- self.assertIsNotNone(cache.objects.get('bug_sharing_policies'))
- self.assertIsNotNone(cache.objects.get('sharing_permissions'))
- batch_size = config.launchpad.default_batch_size
- apgfs = getUtility(IAccessPolicyGrantFlatSource)
- grantees = apgfs.findGranteePermissionsByPolicy(
- [self.access_policy], self.grantees[:batch_size])
- sharing_service = getUtility(IService, 'sharing')
- grantee_data = sharing_service.jsonGranteeData(grantees)
- self.assertContentEqual(
- grantee_data, cache.objects.get('grantee_data'))
+ view = create_initialized_view(self.pillar, name='+sharing')
+ cache = IJSONRequestCache(view.request)
+ self.assertIsNotNone(cache.objects.get('information_types'))
+ self.assertIsNotNone(cache.objects.get('branch_sharing_policies'))
+ self.assertIsNotNone(cache.objects.get('bug_sharing_policies'))
+ self.assertIsNotNone(cache.objects.get('sharing_permissions'))
+ batch_size = config.launchpad.default_batch_size
+ apgfs = getUtility(IAccessPolicyGrantFlatSource)
+ grantees = apgfs.findGranteePermissionsByPolicy(
+ [self.access_policy], self.grantees[:batch_size])
+ sharing_service = getUtility(IService, 'sharing')
+ grantee_data = sharing_service.jsonGranteeData(grantees)
+ self.assertContentEqual(
+ grantee_data, cache.objects.get('grantee_data'))
def test_view_batch_data(self):
# Test the expected batching data is in the json request cache.
- with FeatureFixture(ENABLED_FLAG):
- view = create_initialized_view(self.pillar, name='+sharing')
- cache = IJSONRequestCache(view.request)
- # Test one expected data value (there are many).
- next_batch = view.grantees().batch.nextBatch()
- self.assertContentEqual(
- next_batch.range_memo, cache.objects.get('next')['memo'])
+ view = create_initialized_view(self.pillar, name='+sharing')
+ cache = IJSONRequestCache(view.request)
+ # Test one expected data value (there are many).
+ next_batch = view.grantees().batch.nextBatch()
+ self.assertContentEqual(
+ next_batch.range_memo, cache.objects.get('next')['memo'])
def test_view_range_factory(self):
# Test the view range factory is properly configured.
- with FeatureFixture(ENABLED_FLAG):
- view = create_initialized_view(self.pillar, name='+sharing')
- range_factory = view.grantees().batch.range_factory
-
- def test_range_factory():
- row = range_factory.resultset.get_plain_result_set()[0]
- range_factory.getOrderValuesFor(row)
-
- self.assertThat(
- test_range_factory,
- Not(Raises(MatchesException(StormRangeFactoryError))))
+ view = create_initialized_view(self.pillar, name='+sharing')
+ range_factory = view.grantees().batch.range_factory
+
+ def test_range_factory():
+ row = range_factory.resultset.get_plain_result_set()[0]
+ range_factory.getOrderValuesFor(row)
+
+ self.assertThat(
+ test_range_factory,
+ Not(Raises(MatchesException(StormRangeFactoryError))))
def test_view_query_count(self):
# Test the query count is within expected limit.
- with FeatureFixture(ENABLED_FLAG):
- view = create_view(self.pillar, name='+sharing')
- with StormStatementRecorder() as recorder:
- view.initialize()
- self.assertThat(recorder, HasQueryCount(LessThan(9)))
-
- def test_view_write_enabled_without_feature_flag(self):
- # Test that sharing_write_enabled is not set without the feature flag.
- with FeatureFixture(ENABLED_FLAG):
- login_person(self.owner)
- view = create_initialized_view(self.pillar, name='+sharing')
- cache = IJSONRequestCache(view.request)
- self.assertFalse(cache.objects.get('sharing_write_enabled'))
-
- def test_view_write_enabled_with_feature_flag(self):
- # Test that sharing_write_enabled is set when required.
- with FeatureFixture(WRITE_FLAG):
- view = create_initialized_view(self.pillar, name='+sharing')
- cache = IJSONRequestCache(view.request)
- self.assertFalse(cache.objects.get('sharing_write_enabled'))
- login_person(self.owner)
- view = create_initialized_view(self.pillar, name='+sharing')
- cache = IJSONRequestCache(view.request)
- self.assertTrue(cache.objects.get('sharing_write_enabled'))
+ view = create_view(self.pillar, name='+sharing')
+ with StormStatementRecorder() as recorder:
+ view.initialize()
+ self.assertThat(recorder, HasQueryCount(LessThan(9)))
def test_view_invisible_information_types(self):
# Test the expected invisible information type data is in the
# json request cache.
- with FeatureFixture(WRITE_FLAG):
- with person_logged_in(self.pillar.owner):
- getUtility(IService, 'sharing').deletePillarGrantee(
- self.pillar, self.pillar.owner, self.pillar.owner)
- view = create_initialized_view(self.pillar, name='+sharing')
- cache = IJSONRequestCache(view.request)
- self.assertContentEqual(
- ['Private Security', 'Private'],
- cache.objects.get('invisible_information_types'))
+ with person_logged_in(self.pillar.owner):
+ getUtility(IService, 'sharing').deletePillarGrantee(
+ self.pillar, self.pillar.owner, self.pillar.owner)
+ view = create_initialized_view(self.pillar, name='+sharing')
+ cache = IJSONRequestCache(view.request)
+ self.assertContentEqual(
+ ['Private Security', 'Private'],
+ cache.objects.get('invisible_information_types'))
class TestProductSharingView(PillarSharingViewTestMixin,
=== modified file 'lib/lp/registry/javascript/sharing/pillarsharingview.js'
--- lib/lp/registry/javascript/sharing/pillarsharingview.js 2012-08-23 00:35:25 +0000
+++ lib/lp/registry/javascript/sharing/pillarsharingview.js 2012-08-29 05:40:35 +0000
@@ -19,10 +19,6 @@
value: new Y.lp.client.Launchpad()
},
- write_enabled: {
- value: false
- },
-
grantee_picker: {
value: null
},
@@ -61,12 +57,6 @@
this.set(
'sharing_permissions_by_value', sharing_permissions_by_value);
- // No need to do anything else if we are read only.
- if (LP.cache.sharing_write_enabled !== true) {
- return;
- }
- this.set('write_enabled', true);
-
var vocab;
var header;
var steptitle;
@@ -125,13 +115,11 @@
sharing_permissions:
this.get('sharing_permissions_by_value'),
information_types: this.get('information_types_by_value'),
- write_enabled: this.get('write_enabled')
+ write_enabled: true
});
this.set('grantee_table', grantee_table);
grantee_table.render();
- if (this.get('write_enabled')) {
- Y.one('#add-grantee-link').removeClass('hidden');
- }
+ Y.one('#add-grantee-link').removeClass('hidden');
this.bug_sharing_policy_widget
= this._render_sharing_policy('bug', 'Bug');
this.branch_sharing_policy_widget
@@ -164,8 +152,7 @@
}
choice_items.push.apply(
choice_items, this.getSharingPolicyInformation(artifact_type));
- var editable = LP.cache.sharing_write_enabled
- && choice_items.length > 1;
+ var editable = choice_items.length > 1;
var policy_edit = new Y.ChoiceSource({
flashEnabled: false,
clickable_content: editable,
@@ -186,9 +173,6 @@
},
bindUI: function() {
- if (!this.get('write_enabled')) {
- return;
- }
var self = this;
var share_link = Y.one('#add-grantee-link');
share_link.on('click', function(e) {
=== modified file 'lib/lp/registry/javascript/sharing/sharingdetailsview.js'
--- lib/lp/registry/javascript/sharing/sharingdetailsview.js 2012-07-21 03:04:06 +0000
+++ lib/lp/registry/javascript/sharing/sharingdetailsview.js 2012-08-29 05:40:35 +0000
@@ -19,10 +19,6 @@
value: new Y.lp.client.Launchpad()
},
- write_enabled: {
- value: false
- },
-
sharing_details_table: {
value: null
}
@@ -30,29 +26,19 @@
Y.extend(SharingDetailsView, Y.Widget, {
- initializer: function(config) {
- if (LP.cache.sharing_write_enabled !== true) {
- return;
- }
- this.set('write_enabled', true);
- },
-
renderUI: function() {
var ns = Y.lp.registry.sharing.sharingdetails;
var details_table = new ns.SharingDetailsTable({
bugs: LP.cache.bugs,
branches: LP.cache.branches,
person_name: LP.cache.grantee.displayname,
- write_enabled: this.get('write_enabled')
+ write_enabled: true
});
this.set('sharing_details_table', details_table);
details_table.render();
},
bindUI: function() {
- if (!this.get('write_enabled')) {
- return;
- }
var self = this;
var sharing_details_table = this.get('sharing_details_table');
var ns = Y.lp.registry.sharing.sharingdetails;
=== modified file 'lib/lp/registry/javascript/sharing/tests/test_pillarsharingview.js'
--- lib/lp/registry/javascript/sharing/tests/test_pillarsharingview.js 2012-08-16 00:19:42 +0000
+++ lib/lp/registry/javascript/sharing/tests/test_pillarsharingview.js 2012-08-29 05:40:35 +0000
@@ -56,7 +56,6 @@
title: 'Branch Policy 1',
description: 'Branch Policy 1 description'}
],
- sharing_write_enabled: true
}
};
this.mockio = new Y.lp.testing.mockio.MockIo();
@@ -119,16 +118,6 @@
Y.Assert.isNotNull(Y.one('.yui3-grantee_picker'));
},
- // Read only mode disables the correct things.
- test_readonly: function() {
- window.LP.cache.sharing_write_enabled = false;
- this.view = this._create_Widget();
- this.view.render();
- Y.Assert.isTrue(Y.one('#add-grantee-link').hasClass('hidden'));
- Y.Assert.isFalse(
- this.view.get('grantee_table').get('write_enabled'));
- },
-
// Clicking a update grantee grantee link calls
// the update_grantee_interaction method with the correct parameters.
test_update_grantee_click: function() {
@@ -547,14 +536,6 @@
'Bug Policy 1', value_node.get('text').trim());
},
- // If the view is readonly, no edit links are available.
- test_sharing_policy_render_read_only: function() {
- window.LP.cache.sharing_write_enabled = false;
- this.view = this._create_Widget();
- this.view.render();
- this._assert_sharing_policies_editable(false);
- },
-
// If there is only one policy choice, no edit links are available.
test_sharing_policy_render_only_one_choice: function() {
// Add a model value so the legacy choice is not used.
=== modified file 'lib/lp/registry/javascript/sharing/tests/test_sharingdetailsview.js'
--- lib/lp/registry/javascript/sharing/tests/test_sharingdetailsview.js 2012-07-20 03:15:04 +0000
+++ lib/lp/registry/javascript/sharing/tests/test_sharingdetailsview.js 2012-08-29 05:40:35 +0000
@@ -37,7 +37,6 @@
pillar: {
self_link: '/pillar'
},
- sharing_write_enabled: true
}
};
this.fixture = Y.one('#fixture');
@@ -79,16 +78,6 @@
Y.one('#sharing-table-body tr[id=shared-bug-2]'));
},
- // Read only mode disables the correct things.
- test_readonly: function() {
- window.LP.cache.sharing_write_enabled = false;
- this.view = this._create_Widget();
- this.view.render();
- Y.Assert.isFalse(
- this.view.get('sharing_details_table')
- .get('write_enabled'));
- },
-
// Clicking a bug remove link calls the confirm_grant_removal
// method with the correct parameters.
test_remove_bug_grant_click: function() {
=== modified file 'lib/lp/registry/model/accesspolicy.py'
--- lib/lp/registry/model/accesspolicy.py 2012-08-22 04:58:49 +0000
+++ lib/lp/registry/model/accesspolicy.py 2012-08-29 05:40:35 +0000
@@ -65,14 +65,19 @@
getUtility(IAccessArtifactSource).delete([artifact])
return
[abstract_artifact] = getUtility(IAccessArtifactSource).ensure([artifact])
+ aps = getUtility(IAccessPolicySource).find(
+ (pillar, information_type) for pillar in pillars)
+ missing_pillars = set(pillars) - set([ap.pillar for ap in aps])
+ if len(missing_pillars):
+ pillar_str = ', '.join([p.name for p in missing_pillars])
+ raise AssertionError(
+ "Pillar(s) %s require an access policy for information type "
+ "%s." % (pillar_str, information_type.title))
# Now determine the existing and desired links, and make them
# match.
apasource = getUtility(IAccessPolicyArtifactSource)
- wanted_links = set(
- (abstract_artifact, policy) for policy in
- getUtility(IAccessPolicySource).find(
- (pillar, information_type) for pillar in pillars))
+ wanted_links = set((abstract_artifact, policy) for policy in aps)
existing_links = set([
(apa.abstract_artifact, apa.policy)
for apa in apasource.findByArtifact([abstract_artifact])])
=== modified file 'lib/lp/registry/model/teammembership.py'
--- lib/lp/registry/model/teammembership.py 2012-08-14 23:27:07 +0000
+++ lib/lp/registry/model/teammembership.py 2012-08-29 05:40:35 +0000
@@ -65,7 +65,6 @@
SQLBase,
sqlvalues,
)
-from lp.services.features import getFeatureFlag
from lp.services.mail.helpers import (
get_contact_email_addresses,
get_email_template,
@@ -343,13 +342,11 @@
_fillTeamParticipation(self.person, self.team)
elif old_status in ACTIVE_STATES:
_cleanTeamParticipation(self.person, self.team)
- flag = 'disclosure.unsubscribe_jobs.enabled'
- if bool(getFeatureFlag(flag)):
- # A person has left the team so they may no longer have access
- # to some artifacts shared with the team. We need to run a job
- # to remove any subscriptions to such artifacts.
- getUtility(IRemoveArtifactSubscriptionsJobSource).create(
- user, grantee=self.person)
+ # A person has left the team so they may no longer have access
+ # to some artifacts shared with the team. We need to run a job
+ # to remove any subscriptions to such artifacts.
+ getUtility(IRemoveArtifactSubscriptionsJobSource).create(
+ user, grantee=self.person)
else:
# Changed from an inactive state to another inactive one, so no
# need to fill/clean the TeamParticipation table.
=== modified file 'lib/lp/registry/services/sharingservice.py'
--- lib/lp/registry/services/sharingservice.py 2012-08-16 06:06:36 +0000
+++ lib/lp/registry/services/sharingservice.py 2012-08-29 05:40:35 +0000
@@ -59,7 +59,6 @@
from lp.registry.model.teammembership import TeamParticipation
from lp.services.database.lpstorm import IStore
from lp.services.database.stormexpr import ColumnSelect
-from lp.services.features import getFeatureFlag
from lp.services.searchbuilder import any
from lp.services.webapp.authorization import (
available_with_permission,
@@ -81,12 +80,6 @@
"""See `IService`."""
return 'sharing'
- @property
- def write_enabled(self):
- return (
- bool(getFeatureFlag(
- 'disclosure.enhanced_sharing.writable')))
-
def checkPillarAccess(self, pillar, information_type, person):
"""See `ISharingService`."""
policy = getUtility(IAccessPolicySource).find(
@@ -350,15 +343,12 @@
result = []
request = get_current_web_service_request()
browser_request = IWebBrowserOriginatingRequest(request)
- details_enabled = bool((getFeatureFlag(
- 'disclosure.enhanced_sharing_details.enabled')))
# We need to precache icon and validity information for the batch.
grantee_ids = [grantee[0].id for grantee in grant_permissions]
list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
grantee_ids, need_icon=True, need_validity=True))
for (grantee, permissions, shared_artifact_types) in grant_permissions:
- some_things_shared = (
- details_enabled and len(shared_artifact_types) > 0)
+ some_things_shared = len(shared_artifact_types) > 0
grantee_permissions = {}
for (policy, permission) in permissions.iteritems():
grantee_permissions[policy.type.name] = permission.name
@@ -386,9 +376,6 @@
# We do not support adding grantees to project groups.
assert not IProjectGroup.providedBy(pillar)
- if not self.write_enabled:
- raise Unauthorized("This feature is not yet enabled.")
-
# Separate out the info types according to permission.
information_types = permissions.keys()
info_types_for_all = [
@@ -463,9 +450,6 @@
information_types=None):
"""See `ISharingService`."""
- if not self.write_enabled:
- raise Unauthorized("This feature is not yet enabled.")
-
policy_source = getUtility(IAccessPolicySource)
if information_types is None:
# We delete all policy grants for the pillar.
@@ -491,9 +475,8 @@
to_delete = list(ap_grant_flat.findArtifactsByGrantee(
grantee, pillar_policies))
if len(to_delete) > 0:
- accessartifact_grant_source = getUtility(
- IAccessArtifactGrantSource)
- accessartifact_grant_source.revokeByArtifact(to_delete, [grantee])
+ getUtility(IAccessArtifactGrantSource).revokeByArtifact(
+ to_delete, [grantee])
# Create a job to remove subscriptions for artifacts the grantee can no
# longer see.
@@ -512,9 +495,6 @@
bugs=None):
"""See `ISharingService`."""
- if not self.write_enabled:
- raise Unauthorized("This feature is not yet enabled.")
-
artifacts = []
if branches:
artifacts.extend(branches)
@@ -524,8 +504,7 @@
accessartifact_source = getUtility(IAccessArtifactSource)
artifacts_to_delete = accessartifact_source.find(artifacts)
# Revoke access to bugs/branches for the specified grantee.
- accessartifact_grant_source = getUtility(IAccessArtifactGrantSource)
- accessartifact_grant_source.revokeByArtifact(
+ getUtility(IAccessArtifactGrantSource).revokeByArtifact(
artifacts_to_delete, [grantee])
# Create a job to remove subscriptions for artifacts the grantee can no
@@ -537,9 +516,6 @@
ignore_permissions=False):
"""See `ISharingService`."""
- if not ignore_permissions and not self.write_enabled:
- raise Unauthorized("This feature is not yet enabled.")
-
artifacts = []
if branches:
artifacts.extend(branches)
=== modified file 'lib/lp/registry/services/tests/test_sharingservice.py'
--- lib/lp/registry/services/tests/test_sharingservice.py 2012-08-16 06:06:36 +0000
+++ lib/lp/registry/services/tests/test_sharingservice.py 2012-08-29 05:40:35 +0000
@@ -56,13 +56,6 @@
from lp.testing.pages import LaunchpadWebServiceCaller
-WRITE_FLAG = {
- 'disclosure.enhanced_sharing.writable': 'true',
- 'disclosure.enhanced_sharing_details.enabled': 'true',
- 'jobs.celery.enabled_classes': 'RemoveArtifactSubscriptionsJob'}
-DETAILS_FLAG = {'disclosure.enhanced_sharing_details.enabled': 'true'}
-
-
class TestSharingService(TestCaseWithFactory):
"""Tests for the SharingService."""
@@ -71,6 +64,9 @@
def setUp(self):
super(TestSharingService, self).setUp()
self.service = getUtility(IService, 'sharing')
+ self.useFixture(FeatureFixture({
+ 'jobs.celery.enabled_classes': 'RemoveArtifactSubscriptionsJob',
+ }))
def _makeGranteeData(self, grantee, policy_permissions,
shared_artifact_types):
@@ -234,12 +230,11 @@
[policy1, policy2] = getUtility(IAccessPolicySource).findByPillar(
[product])
grantee = self.factory.makePerson()
- with FeatureFixture(DETAILS_FLAG):
- grantees = self.service.jsonGranteeData(
- [(grantee, {
- policy1: SharingPermission.ALL,
- policy2: SharingPermission.SOME},
- [policy1.type, policy2.type])])
+ grantees = self.service.jsonGranteeData(
+ [(grantee, {
+ policy1: SharingPermission.ALL,
+ policy2: SharingPermission.SOME},
+ [policy1.type, policy2.type])])
expected_data = self._makeGranteeData(
grantee,
[(policy1.type, SharingPermission.ALL),
@@ -247,24 +242,6 @@
[policy1.type, policy2.type])
self.assertContentEqual([expected_data], grantees)
- def test_jsonGranteeData_with_Some_without_flag(self):
- # jsonGranteeData returns the expected data for a grantee with
- # permissions which include SOME and the feature flag not set.
- product = self.factory.makeProduct()
- [policy1, policy2] = getUtility(IAccessPolicySource).findByPillar(
- [product])
- grantee = self.factory.makePerson()
- grantees = self.service.jsonGranteeData(
- [(grantee, {
- policy1: SharingPermission.ALL,
- policy2: SharingPermission.SOME}, [policy2.type])])
- expected_data = self._makeGranteeData(
- grantee,
- [(policy1.type, SharingPermission.ALL),
- (policy2.type, SharingPermission.SOME)], [policy2.type])
- expected_data['shared_items_exist'] = False
- self.assertContentEqual([expected_data], grantees)
-
def test_jsonGranteeData_without_Some(self):
# jsonGranteeData returns the expected data for a grantee with only ALL
# permissions.
@@ -272,10 +249,8 @@
[policy1, policy2] = getUtility(IAccessPolicySource).findByPillar(
[product])
grantee = self.factory.makePerson()
- with FeatureFixture(DETAILS_FLAG):
- grantees = self.service.jsonGranteeData(
- [(grantee, {
- policy1: SharingPermission.ALL}, [])])
+ grantees = self.service.jsonGranteeData(
+ [(grantee, {policy1: SharingPermission.ALL}, [])])
expected_data = self._makeGranteeData(
grantee,
[(policy1.type, SharingPermission.ALL)], [])
@@ -290,10 +265,8 @@
icon = self.factory.makeLibraryFileAlias(
filename='smurf.png', content_type='image/png')
grantee = self.factory.makeTeam(icon=icon)
- with FeatureFixture(DETAILS_FLAG):
- grantees = self.service.jsonGranteeData(
- [(grantee, {
- policy1: SharingPermission.ALL}, [])])
+ grantees = self.service.jsonGranteeData(
+ [(grantee, {policy1: SharingPermission.ALL}, [])])
expected_data = self._makeGranteeData(
grantee,
[(policy1.type, SharingPermission.ALL)], [])
@@ -312,8 +285,7 @@
self.factory.makeAccessPolicyArtifact(
artifact=artifact_grant.abstract_artifact, policy=access_policy)
- with FeatureFixture(DETAILS_FLAG):
- grantees = self.service.getPillarGranteeData(pillar)
+ grantees = self.service.getPillarGranteeData(pillar)
expected_grantees = [
self._makeGranteeData(
grantee,
@@ -540,9 +512,8 @@
InformationType.PRIVATESECURITY: SharingPermission.ALL,
InformationType.USERDATA: SharingPermission.SOME,
InformationType.PROPRIETARY: SharingPermission.NOTHING}
- with FeatureFixture(WRITE_FLAG):
- grantee_data = self.service.sharePillarInformation(
- pillar, grantee, grantor, permissions)
+ grantee_data = self.service.sharePillarInformation(
+ pillar, grantee, grantor, permissions)
policies = getUtility(IAccessPolicySource).findByPillar([pillar])
policy_grant_source = getUtility(IAccessPolicyGrantSource)
grants = policy_grant_source.findByPolicy(policies)
@@ -619,9 +590,8 @@
permissions = {
grant.policy.type: SharingPermission.SOME}
- with FeatureFixture(WRITE_FLAG):
- grantee_data = self.service.sharePillarInformation(
- pillar, grantee, self.factory.makePerson(), permissions)
+ grantee_data = self.service.sharePillarInformation(
+ pillar, grantee, self.factory.makePerson(), permissions)
self.assertIsNone(grantee_data['grantee_entry'])
def test_granteePillarInformationInvisibleInformationTypes(self):
@@ -629,13 +599,12 @@
# information types.
product = self.factory.makeProduct()
grantee = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- with admin_logged_in():
- self.service.deletePillarGrantee(
- product, product.owner, product.owner)
- result_data = self.service.sharePillarInformation(
- product, grantee, product.owner,
- {InformationType.USERDATA: SharingPermission.ALL})
+ with admin_logged_in():
+ self.service.deletePillarGrantee(
+ product, product.owner, product.owner)
+ result_data = self.service.sharePillarInformation(
+ product, grantee, product.owner,
+ {InformationType.USERDATA: SharingPermission.ALL})
# The owner is granted access on product creation. So we need to allow
# for that in the check below.
self.assertContentEqual(
@@ -645,42 +614,27 @@
def _assert_sharePillarInformationUnauthorized(self, pillar):
# sharePillarInformation raises an Unauthorized exception if the user
# is not permitted to do so.
- with FeatureFixture(WRITE_FLAG):
- grantee = self.factory.makePerson()
- user = self.factory.makePerson()
- self.assertRaises(
- Unauthorized, self.service.sharePillarInformation,
- pillar, grantee, user,
- {InformationType.USERDATA: SharingPermission.ALL})
+ grantee = self.factory.makePerson()
+ user = self.factory.makePerson()
+ self.assertRaises(
+ Unauthorized, self.service.sharePillarInformation,
+ pillar, grantee, user,
+ {InformationType.USERDATA: SharingPermission.ALL})
def test_sharePillarInformationAnonymous(self):
# Anonymous users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- product = self.factory.makeProduct()
- login(ANONYMOUS)
- self._assert_sharePillarInformationUnauthorized(product)
+ product = self.factory.makeProduct()
+ login(ANONYMOUS)
+ self._assert_sharePillarInformationUnauthorized(product)
def test_sharePillarInformationAnyone(self):
# Unauthorized users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- product = self.factory.makeProduct()
- login_person(self.factory.makePerson())
- self._assert_sharePillarInformationUnauthorized(product)
-
- def test_sharePillarInformation_without_flag(self):
- # The feature flag needs to be enabled.
- owner = self.factory.makePerson()
- product = self.factory.makeProduct(owner=owner)
- login_person(owner)
- grantee = self.factory.makePerson()
- user = self.factory.makePerson()
- self.assertRaises(
- Unauthorized, self.service.sharePillarInformation,
- product, grantee, user,
- {InformationType.USERDATA: SharingPermission.ALL})
-
- def _assert_deletePillarGrantee(
- self, pillar, types_to_delete=None, pillar_type=None):
+ product = self.factory.makeProduct()
+ login_person(self.factory.makePerson())
+ self._assert_sharePillarInformationUnauthorized(product)
+
+ def _assert_deletePillarGrantee(self, pillar, types_to_delete=None,
+ pillar_type=None):
access_policies = getUtility(IAccessPolicySource).findByPillar(
(pillar,))
information_types = [ap.type for ap in access_policies]
@@ -701,9 +655,8 @@
self.factory.makeAccessPolicyArtifact(
artifact=artifact, policy=access_policy)
# Delete data for a specific information type.
- with FeatureFixture(WRITE_FLAG):
- self.service.deletePillarGrantee(
- pillar, grantee, pillar.owner, types_to_delete)
+ self.service.deletePillarGrantee(
+ pillar, grantee, pillar.owner, types_to_delete)
# Assemble the expected data for the remaining access grants for
# grantee.
expected_data = []
@@ -768,43 +721,30 @@
def test_deletePillarGranteeInvisibleInformationTypes(self):
# Deleting a pillar grantee returns the resulting invisible info types.
product = self.factory.makeProduct()
- with FeatureFixture(WRITE_FLAG):
- with admin_logged_in():
- invisible_information_types = self.service.deletePillarGrantee(
- product, product.owner, product.owner)
+ with admin_logged_in():
+ invisible_information_types = self.service.deletePillarGrantee(
+ product, product.owner, product.owner)
self.assertContentEqual(
['Private', 'Private Security'], invisible_information_types)
def _assert_deletePillarGranteeUnauthorized(self, pillar):
# deletePillarGrantee raises an Unauthorized exception if the user
# is not permitted to do so.
- with FeatureFixture(WRITE_FLAG):
- self.assertRaises(
- Unauthorized, self.service.deletePillarGrantee,
- pillar, pillar.owner, pillar.owner, [InformationType.USERDATA])
+ self.assertRaises(
+ Unauthorized, self.service.deletePillarGrantee,
+ pillar, pillar.owner, pillar.owner, [InformationType.USERDATA])
def test_deletePillarGranteeAnonymous(self):
# Anonymous users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- product = self.factory.makeProduct()
- login(ANONYMOUS)
- self._assert_deletePillarGranteeUnauthorized(product)
+ product = self.factory.makeProduct()
+ login(ANONYMOUS)
+ self._assert_deletePillarGranteeUnauthorized(product)
def test_deletePillarGranteeAnyone(self):
# Unauthorized users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- product = self.factory.makeProduct()
- login_person(self.factory.makePerson())
- self._assert_deletePillarGranteeUnauthorized(product)
-
- def test_deletePillarGrantee_without_flag(self):
- # The feature flag needs to be enabled.
- owner = self.factory.makePerson()
- product = self.factory.makeProduct(owner=owner)
- login_person(owner)
- self.assertRaises(
- Unauthorized, self.service.deletePillarGrantee,
- product, product.owner, product.owner, [InformationType.USERDATA])
+ product = self.factory.makeProduct()
+ login_person(self.factory.makePerson())
+ self._assert_deletePillarGranteeUnauthorized(product)
def _assert_deleteGranteeRemoveSubscriptions(self,
types_to_delete=None):
@@ -839,9 +779,8 @@
bug.subscribe(person, product.owner)
# Delete data for specified information types or all.
- with FeatureFixture(WRITE_FLAG):
- self.service.deletePillarGrantee(
- product, grantee, product.owner, types_to_delete)
+ self.service.deletePillarGrantee(
+ product, grantee, product.owner, types_to_delete)
with block_on_job(self):
transaction.commit()
@@ -907,9 +846,8 @@
apgfs = getUtility(IAccessPolicyGrantFlatSource)
self.assertEqual(1, grants.count())
- with FeatureFixture(WRITE_FLAG):
- self.service.revokeAccessGrants(
- pillar, grantee, pillar.owner, bugs=bugs, branches=branches)
+ self.service.revokeAccessGrants(
+ pillar, grantee, pillar.owner, bugs=bugs, branches=branches)
with block_on_job(self):
transaction.commit()
@@ -993,10 +931,8 @@
for bug in bugs or []:
self.assertIn(person, bug.getDirectSubscribers())
- with FeatureFixture(WRITE_FLAG):
- self.service.revokeAccessGrants(
- pillar, team_grantee, pillar.owner,
- bugs=bugs, branches=branches)
+ self.service.revokeAccessGrants(
+ pillar, team_grantee, pillar.owner, bugs=bugs, branches=branches)
with block_on_job(self):
transaction.commit()
@@ -1042,43 +978,27 @@
bug = self.factory.makeBug(
target=product, information_type=InformationType.USERDATA)
grantee = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- self.assertRaises(
- Unauthorized, self.service.revokeAccessGrants,
- product, grantee, product.owner, bugs=[bug])
+ self.assertRaises(
+ Unauthorized, self.service.revokeAccessGrants,
+ product, grantee, product.owner, bugs=[bug])
def test_revokeAccessGrantsAnonymous(self):
# Anonymous users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- login(ANONYMOUS)
- self._assert_revokeAccessGrantsUnauthorized()
+ login(ANONYMOUS)
+ self._assert_revokeAccessGrantsUnauthorized()
def test_revokeAccessGrantsAnyone(self):
# Unauthorized users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- login_person(self.factory.makePerson())
- self._assert_revokeAccessGrantsUnauthorized()
-
- def test_revokeAccessGrants_without_flag(self):
- # The feature flag needs to be enabled.
- owner = self.factory.makePerson()
- product = self.factory.makeProduct(owner=owner)
- bug = self.factory.makeBug(
- target=product, information_type=InformationType.USERDATA)
- grantee = self.factory.makePerson()
- login_person(owner)
- self.assertRaises(
- Unauthorized, self.service.revokeAccessGrants,
- product, grantee, product.owner, bugs=[bug])
+ login_person(self.factory.makePerson())
+ self._assert_revokeAccessGrantsUnauthorized()
def _assert_ensureAccessGrants(self, user, bugs, branches,
grantee=None):
# Creating access grants works as expected.
if not grantee:
grantee = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- self.service.ensureAccessGrants(
- [grantee], user, bugs=bugs, branches=branches)
+ self.service.ensureAccessGrants(
+ [grantee], user, bugs=bugs, branches=branches)
# Check that grantee has expected access grants.
shared_bugs = []
@@ -1133,8 +1053,7 @@
information_type=InformationType.USERDATA)
# Create an existing access grant.
grantee = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- self.service.ensureAccessGrants([grantee], owner, bugs=[bug])
+ self.service.ensureAccessGrants([grantee], owner, bugs=[bug])
# Test with a new bug as well as the one for which access is already
# granted.
self._assert_ensureAccessGrants(owner, [bug, bug2], None, grantee)
@@ -1146,35 +1065,20 @@
bug = self.factory.makeBug(
target=product, information_type=InformationType.USERDATA)
grantee = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- self.assertRaises(
- Unauthorized, self.service.ensureAccessGrants,
- [grantee], user, bugs=[bug])
+ self.assertRaises(
+ Unauthorized, self.service.ensureAccessGrants, [grantee], user,
+ bugs=[bug])
def test_ensureAccessGrantsAnonymous(self):
# Anonymous users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- login(ANONYMOUS)
- self._assert_ensureAccessGrantsUnauthorized(ANONYMOUS)
+ login(ANONYMOUS)
+ self._assert_ensureAccessGrantsUnauthorized(ANONYMOUS)
def test_ensureAccessGrantsAnyone(self):
# Unauthorized users are not allowed.
- with FeatureFixture(WRITE_FLAG):
- anyone = self.factory.makePerson()
- login_person(anyone)
- self._assert_ensureAccessGrantsUnauthorized(anyone)
-
- def test_ensureAccessGrants_without_flag(self):
- # The feature flag needs to be enabled.
- owner = self.factory.makePerson()
- product = self.factory.makeProduct(owner=owner)
- bug = self.factory.makeBug(
- target=product, information_type=InformationType.USERDATA)
- grantee = self.factory.makePerson()
- login_person(owner)
- self.assertRaises(
- Unauthorized, self.service.ensureAccessGrants,
- [grantee], product.owner, bugs=[bug])
+ anyone = self.factory.makePerson()
+ login_person(anyone)
+ self._assert_ensureAccessGrantsUnauthorized(anyone)
def test_getSharedArtifacts(self):
# Test the getSharedArtifacts method.
@@ -1385,14 +1289,13 @@
right_person = self.factory.makePerson()
right_team = self.factory.makeTeam(members=[right_person])
wrong_person = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- with admin_logged_in():
- self.service.sharePillarInformation(
- product, right_team, product.owner,
- {InformationType.USERDATA: SharingPermission.ALL})
- self.service.sharePillarInformation(
- product, wrong_person, product.owner,
- {InformationType.PRIVATESECURITY: SharingPermission.ALL})
+ with admin_logged_in():
+ self.service.sharePillarInformation(
+ product, right_team, product.owner,
+ {InformationType.USERDATA: SharingPermission.ALL})
+ self.service.sharePillarInformation(
+ product, wrong_person, product.owner,
+ {InformationType.PRIVATESECURITY: SharingPermission.ALL})
self.assertEqual(
False,
self.service.checkPillarAccess(
@@ -1415,11 +1318,10 @@
# an information type.
product = self.factory.makeProduct()
grantee = self.factory.makePerson()
- with FeatureFixture(WRITE_FLAG):
- with admin_logged_in():
- self.service.sharePillarInformation(
- product, grantee, product.owner,
- {InformationType.USERDATA: SharingPermission.ALL})
+ with admin_logged_in():
+ self.service.sharePillarInformation(
+ product, grantee, product.owner,
+ {InformationType.USERDATA: SharingPermission.ALL})
# The owner is granted access on product creation. So we need to allow
# for that in the check below.
self.assertContentEqual(
@@ -1431,10 +1333,9 @@
# checkPillarAccess checks whether the user has full access to
# an information type.
product = self.factory.makeProduct()
- with FeatureFixture(WRITE_FLAG):
- with admin_logged_in():
- self.service.deletePillarGrantee(
- product, product.owner, product.owner)
+ with admin_logged_in():
+ self.service.deletePillarGrantee(
+ product, product.owner, product.owner)
self.assertContentEqual(
[(InformationType.PRIVATESECURITY, 0),
(InformationType.USERDATA, 0)],
@@ -1499,14 +1400,13 @@
def _sharePillarInformation(self):
pillar_uri = canonical_url(self.pillar, force_local_path=True)
- with FeatureFixture(WRITE_FLAG):
- return self._named_post(
- 'sharePillarInformation', pillar=pillar_uri,
- grantee=self.grantee_uri,
- user=self.grantor_uri,
- permissions={
- InformationType.USERDATA.title:
- SharingPermission.ALL.title})
+ return self._named_post(
+ 'sharePillarInformation', pillar=pillar_uri,
+ grantee=self.grantee_uri,
+ user=self.grantor_uri,
+ permissions={
+ InformationType.USERDATA.title:
+ SharingPermission.ALL.title})
class TestLaunchpadlib(ApiTestMixin, TestCaseWithFactory):
@@ -1518,9 +1418,6 @@
super(TestLaunchpadlib, self).setUp()
self.launchpad = self.factory.makeLaunchpadService(person=self.owner)
self.service = self.launchpad.load('+services/sharing')
- flag = FeatureFixture(WRITE_FLAG)
- flag.setUp()
- self.addCleanup(flag.cleanUp)
transaction.commit()
self._sharePillarInformation()
=== modified file 'lib/lp/registry/tests/test_accesspolicy.py'
--- lib/lp/registry/tests/test_accesspolicy.py 2012-08-08 07:22:51 +0000
+++ lib/lp/registry/tests/test_accesspolicy.py 2012-08-29 05:40:35 +0000
@@ -725,3 +725,20 @@
reconcile_access_for_artifact(
bug, InformationType.USERDATA, [product])
self.assertPoliciesForBug([(product, InformationType.USERDATA)], bug)
+
+ def test_raises_exception_on_missing_policies(self):
+ # reconcile_access_for_artifact raises an exception if a pillar is
+ # missing an AccessPolicy.
+ product = self.factory.makeProduct()
+ # Creating a product will have created two APs, delete them.
+ aps = getUtility(IAccessPolicySource).findByPillar([product])
+ getUtility(IAccessPolicyGrantSource).revokeByPolicy(aps)
+ for ap in aps:
+ IStore(ap).remove(ap)
+ bug = self.factory.makeBug(target=product)
+ expected = (
+ "Pillar(s) %s require an access policy for information type "
+ "Private.") % product.name
+ self.assertRaisesWithContent(
+ AssertionError, expected, reconcile_access_for_artifact, bug,
+ InformationType.USERDATA, [product])
=== modified file 'lib/lp/registry/tests/test_teammembership.py'
--- lib/lp/registry/tests/test_teammembership.py 2012-08-14 23:27:07 +0000
+++ lib/lp/registry/tests/test_teammembership.py 2012-08-29 05:40:35 +0000
@@ -504,7 +504,7 @@
The number of db queries should be constant not O(depth).
"""
self.assertStatementCount(
- 7,
+ 9,
self.team5.setMembershipData, self.no_priv,
TeamMembershipStatus.DEACTIVATED, self.team5.teamowner)
@@ -998,7 +998,6 @@
def setUp(self):
self.useFixture(FeatureFixture({
- 'disclosure.unsubscribe_jobs.enabled': 'true',
'jobs.celery.enabled_classes': 'RemoveArtifactSubscriptionsJob',
}))
super(TestTeamMembershipJobs, self).setUp()
=== modified file 'lib/lp/services/features/flags.py'
--- lib/lp/services/features/flags.py 2012-08-14 18:51:43 +0000
+++ lib/lp/services/features/flags.py 2012-08-29 05:40:35 +0000
@@ -197,12 +197,6 @@
'',
'',
''),
- ('disclosure.add-team-person-picker.enabled',
- 'boolean',
- 'Allows users to add a new team directly from the person picker.',
- '',
- '',
- ''),
('bugs.autoconfirm.enabled_distribution_names',
'space delimited',
('Enables auto-confirming bugtasks for distributions (and their '
@@ -233,34 +227,6 @@
'',
'',
''),
- ('disclosure.enhanced_sharing.enabled',
- 'boolean',
- ('If true, will allow the use of the new sharing view and apis used '
- 'for the new disclosure data model to view but not write data.'),
- '',
- 'Sharing overview',
- ''),
- ('disclosure.enhanced_sharing_details.enabled',
- 'boolean',
- ('If true, enables the details page for viewing the `Some` things that'
- 'shared with a user or team.'),
- '',
- '',
- ''),
- ('disclosure.enhanced_sharing.writable',
- 'boolean',
- ('If true, will allow the use of the new sharing view and apis used '
- 'to edit the new disclosure data model.'),
- '',
- 'Sharing management',
- ''),
- ('disclosure.unsubscribe_jobs.enabled',
- 'boolean',
- ('If true, the jobs to unsubscribe users who lose access to bugs'
- 'and branches are run.'),
- '',
- '',
- ''),
('registry.upcoming_work_view.enabled',
'boolean',
('If true, the new upcoming work view of teams is available.'),
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2012-08-21 04:28:11 +0000
+++ lib/lp/testing/factory.py 2012-08-29 05:40:35 +0000
@@ -1688,6 +1688,8 @@
target = series.pillar
else:
target = self.makeProduct()
+ if information_type == InformationType.PROPRIETARY:
+ self.makeAccessPolicy(pillar=target)
if IDistributionSourcePackage.providedBy(target):
self.makeSourcePackagePublishingHistory(
distroseries=target.distribution.currentseries,
=== modified file 'versions.cfg'
--- versions.cfg 2012-08-23 02:40:39 +0000
+++ versions.cfg 2012-08-29 05:40:35 +0000
@@ -10,7 +10,7 @@
argparse = 1.2.1
auditor = 0.0.3
auditorclient = 0.0.2
-auditorfixture = 0.0.4
+auditorfixture = 0.0.5
BeautifulSoup = 3.1.0.1
bson = 0.3.2
# The source for this version of bzr is at lp:~benji/bzr/bug-998040