← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/drop-disclosure-feature-flags into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/drop-disclosure-feature-flags into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/drop-disclosure-feature-flags/+merge/121523

Destroy all disclosure feature flags I can, namely:

* disclosure.add-team-person-picker.enabled
* disclosure.enhanced_sharing.enabled
* disclosure.enhanced_sharing_details.enabled
* disclosure.enhanced_sharing.writable
* disclosure.unsubscribe_jobs.enabled

There were a bunch of tests that tested that things didn't work or raised Unauthorized which I just removed. It seems like to me that the test changes in lib/lp/bugs/model/tests/test_bug.py were dependent on the unsubscription happening with the feature flag off, and I've changed the check calls to filter the results by who has access.

The bugsubscription.txt case seems to be more contrived. We subscribe Mark, and then switch the bug to private and check he isn't subscribed, and then flip the bug to public, and he still isn't subscribed.
-- 
https://code.launchpad.net/~stevenk/launchpad/drop-disclosure-feature-flags/+merge/121523
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/drop-disclosure-feature-flags into lp:launchpad.
=== 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-28 01:44:29 +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-28 01:44:29 +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/widgets/popup.py'
--- lib/lp/app/widgets/popup.py	2012-07-07 14:00:30 +0000
+++ lib/lp/app/widgets/popup.py	2012-08-28 01:44:29 +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
 
@@ -60,9 +59,7 @@
 
     @property
     def enhanced_picker(self):
-        flag = getFeatureFlag(
-            "disclosure.add-team-person-picker.enabled")
-        return flag and self.show_create_team_link
+        return self.show_create_team_link
 
     @cachedproperty
     def matches(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-28 01:44:29 +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,15 @@
         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'])
+        self.assertTrue(picker_widget.config['enhanced_picker'])
 
     def test_widget_personvalue_meta(self):
         # The person picker has the correct meta value for a person value.

=== 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-28 01:44:29 +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/model/bug.py'
--- lib/lp/bugs/model/bug.py	2012-08-23 04:20:48 +0000
+++ lib/lp/bugs/model/bug.py	2012-08-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-27 23:58:18 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py	2012-08-28 01:44:29 +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()

=== 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-28 01:44:29 +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/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-28 01:44:29 +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_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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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/teammembership.py'
--- lib/lp/registry/model/teammembership.py	2012-08-14 23:27:07 +0000
+++ lib/lp/registry/model/teammembership.py	2012-08-28 01:44:29 +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-28 01:44:29 +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-28 01:44:29 +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_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-28 01:44:29 +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-28 01:44:29 +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.'),


Follow ups