← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wallyworld/launchpad/delete-RemoveGranteeSubscriptionsJob into lp:launchpad

 

Ian Booth has proposed merging lp:~wallyworld/launchpad/delete-RemoveGranteeSubscriptionsJob into lp:launchpad with lp:~wallyworld/launchpad/unshare-team-members-subscriptions2-1009358 as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/delete-RemoveGranteeSubscriptionsJob/+merge/110223

Delete RemoveGranteeSubscriptionJob since it's now no longer used.
-- 
https://code.launchpad.net/~wallyworld/launchpad/delete-RemoveGranteeSubscriptionsJob/+merge/110223
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/delete-RemoveGranteeSubscriptionsJob into lp:launchpad.
=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml	2012-05-29 03:59:16 +0000
+++ lib/lp/registry/configure.zcml	2012-06-14 03:51:25 +0000
@@ -1985,19 +1985,6 @@
     </securedutility>
 
     <!-- Sharing jobs -->
-    <class class=".model.sharingjob.RemoveGranteeSubscriptionsJob">
-      <allow interface=".interfaces.sharingjob.IRemoveGranteeSubscriptionsJob"/>
-      <allow attributes="
-         context
-         log_name"/>
-    </class>
-
-    <securedutility
-        component=".model.sharingjob.RemoveGranteeSubscriptionsJob"
-        provides=".interfaces.sharingjob.IRemoveGranteeSubscriptionsJobSource">
-      <allow interface=".interfaces.sharingjob.IRemoveGranteeSubscriptionsJobSource"/>
-    </securedutility>
-
     <class class=".model.sharingjob.RemoveBugSubscriptionsJob">
       <allow interface=".interfaces.sharingjob.IRemoveBugSubscriptionsJob"/>
       <allow attributes="

=== modified file 'lib/lp/registry/interfaces/sharingjob.py'
--- lib/lp/registry/interfaces/sharingjob.py	2012-06-14 03:51:24 +0000
+++ lib/lp/registry/interfaces/sharingjob.py	2012-06-14 03:51:25 +0000
@@ -8,8 +8,6 @@
 __all__ = [
     'IRemoveBugSubscriptionsJob',
     'IRemoveBugSubscriptionsJobSource',
-    'IRemoveGranteeSubscriptionsJob',
-    'IRemoveGranteeSubscriptionsJobSource',
     'ISharingJob',
     'ISharingJobSource',
     ]
@@ -75,13 +73,6 @@
     """
 
 
-class IRemoveGranteeSubscriptionsJob(ISharingJob):
-    """Job to remove subscriptions to artifacts for which access is revoked.
-
-    Invalid subscription for a specific grantee are removed.
-    """
-
-
 class ISharingJobSource(IJobSource):
     """Base interface for acquiring ISharingJobs."""
 
@@ -98,14 +89,3 @@
         Subscriptions for users who no longer have access to the bugs are
         removed.
         """
-
-
-class IRemoveGranteeSubscriptionsJobSource(ISharingJobSource):
-    """An interface for acquiring IRemoveGranteeSubscriptionsJobs."""
-
-    def create(pillar, grantee, requestor, bugs=None, branches=None):
-        """Create a new job to revoke access to the specified artifacts.
-
-        If bug and branches are both None, then all subscriptions the grantee
-        may have to any pillar artifacts are removed.
-        """

=== modified file 'lib/lp/registry/model/sharingjob.py'
--- lib/lp/registry/model/sharingjob.py	2012-06-14 03:51:24 +0000
+++ lib/lp/registry/model/sharingjob.py	2012-06-14 03:51:25 +0000
@@ -9,7 +9,6 @@
 
 __all__ = [
     'RemoveBugSubscriptionsJob',
-    'RemoveGranteeSubscriptionsJob',
     ]
 
 import contextlib
@@ -46,22 +45,17 @@
     )
 
 from lp.bugs.interfaces.bug import IBugSet
-from lp.bugs.model.bug import Bug
 from lp.bugs.model.bugsubscription import BugSubscription
 from lp.bugs.model.bugtaskflat import BugTaskFlat
 from lp.bugs.model.bugtasksearch import (
-    get_bug_privacy_filter,
     get_bug_privacy_filter_terms,
     )
-from lp.code.interfaces.branchlookup import IBranchLookup
 from lp.registry.enums import InformationType
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.product import IProduct
 from lp.registry.interfaces.sharingjob import (
     IRemoveBugSubscriptionsJob,
     IRemoveBugSubscriptionsJobSource,
-    IRemoveGranteeSubscriptionsJob,
-    IRemoveGranteeSubscriptionsJobSource,
     ISharingJob,
     ISharingJobSource,
     )
@@ -257,142 +251,6 @@
         return vars
 
 
-class RemoveGranteeSubscriptionsJob(SharingJobDerived):
-    """See `IRemoveGranteeSubscriptionsJob`."""
-
-    implements(IRemoveGranteeSubscriptionsJob)
-    classProvides(IRemoveGranteeSubscriptionsJobSource)
-    class_job_type = SharingJobType.REMOVE_GRANTEE_SUBSCRIPTIONS
-
-    config = config.IRemoveGranteeSubscriptionsJobSource
-
-    @classmethod
-    def create(cls, pillar, grantee, requestor, information_types=None,
-               bugs=None, branches=None):
-        """See `IRemoveGranteeSubscriptionsJob`."""
-
-        bug_ids = [
-            bug.id for bug in bugs or []
-        ]
-        branch_names = [
-            branch.unique_name for branch in branches or []
-        ]
-        information_types = [
-            info_type.value for info_type in information_types or []
-        ]
-        metadata = {
-            'bug_ids': bug_ids,
-            'branch_names': branch_names,
-            'information_types': information_types,
-            'requestor.id': requestor.id
-        }
-        return super(RemoveGranteeSubscriptionsJob, cls).create(
-            pillar, grantee, metadata)
-
-    @property
-    def requestor_id(self):
-        return self.metadata['requestor.id']
-
-    @property
-    def requestor(self):
-        return getUtility(IPersonSet).get(self.requestor_id)
-
-    @property
-    def bug_ids(self):
-        return self.metadata['bug_ids']
-
-    @property
-    def branch_names(self):
-        return self.metadata['branch_names']
-
-    @property
-    def information_types(self):
-        return [
-            enumerated_type_registry[InformationType.name].items[value]
-            for value in self.metadata['information_types']]
-
-    def getErrorRecipients(self):
-        # If something goes wrong we want to let the requestor know as well
-        # as the pillar maintainer (if there is a pillar).
-        result = set()
-        result.add(format_address_for_person(self.requestor))
-        if self.pillar and self.pillar.owner.preferredemail:
-            result.add(format_address_for_person(self.pillar.owner))
-        return list(result)
-
-    def getOperationDescription(self):
-        return ('removing subscriptions for artifacts '
-            'for %s on %s' % (self.grantee.displayname, self.pillar_text))
-
-    def run(self):
-        """See `IRemoveGranteeSubscriptionsJob`."""
-
-        logger = logging.getLogger()
-        logger.info(self.getOperationDescription())
-
-        # Unsubscribe grantee from the specified bugs if they can't see the
-        # bug.
-        if self.bug_ids:
-            bugs = getUtility(IBugSet).getByNumbers(self.bug_ids)
-            inaccessible_bugs = [
-                bug for bug in bugs if not bug.userCanView(self.grantee)]
-            for bug in inaccessible_bugs:
-                bug.unsubscribe(
-                    self.grantee, self.requestor, ignore_permissions=True)
-
-        # Unsubscribe grantee from the specified branches if they can't see the
-        # branch.
-        if self.branch_names:
-            branches = [
-                getUtility(IBranchLookup).getByUniqueName(branch_name)
-                for branch_name in self.branch_names]
-            inaccessible_branches = [
-                branch for branch in branches
-                if not branch.visibleByUser(self.grantee)
-            ]
-            for branch in inaccessible_branches:
-                branch.unsubscribe(
-                    self.grantee, self.requestor, ignore_permissions=True)
-
-        # If required, unsubscribe all pillar artifacts.
-        if not self.bug_ids and not self.branch_names:
-            self._unsubscribe_pillar_artifacts(self.information_types)
-
-    def _unsubscribe_pillar_artifacts(self, only_information_types):
-        # Unsubscribe grantee from pillar artifacts to which they no longer
-        # have access. If only_information_types is specified, filter by the
-        # specified information types, else unsubscribe from all artifacts.
-
-        # Branches are not handled until information_type is supported.
-
-        # Do the bugs.
-        privacy_filter = get_bug_privacy_filter(self.grantee)
-
-        # Admins can see all bugs so there's nothing to do.
-        if not privacy_filter:
-            return
-
-        bug_filter = Not(In(
-            Bug.id,
-            Select(
-                (BugTaskFlat.bug_id,),
-                where=privacy_filter)))
-        if only_information_types:
-            bug_filter = And(
-                bug_filter,
-                Bug.information_type.is_in(only_information_types)
-            )
-        store = IStore(BugSubscription)
-        subscribed_invisible_bugs = store.find(
-            Bug,
-            BugSubscription.bug_id == Bug.id,
-            BugSubscription.person == self.grantee,
-            bug_filter)
-        for bug in subscribed_invisible_bugs:
-            bug.unsubscribe(
-                self.grantee, self.requestor, ignore_permissions=True)
-
-
 class RemoveBugSubscriptionsJob(SharingJobDerived):
     """See `IRemoveBugSubscriptionsJob`."""
 

=== modified file 'lib/lp/registry/tests/test_sharingjob.py'
--- lib/lp/registry/tests/test_sharingjob.py	2012-06-14 03:51:24 +0000
+++ lib/lp/registry/tests/test_sharingjob.py	2012-06-14 03:51:25 +0000
@@ -13,10 +13,6 @@
 from zope.security.proxy import removeSecurityProxy
 
 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
-from lp.code.enums import (
-    BranchSubscriptionNotificationLevel,
-    CodeReviewNotificationLevel,
-    )
 from lp.registry.enums import InformationType
 from lp.registry.interfaces.accesspolicy import (
     IAccessArtifactSource,
@@ -26,14 +22,12 @@
 from lp.registry.interfaces.person import TeamSubscriptionPolicy
 from lp.registry.interfaces.sharingjob import (
     IRemoveBugSubscriptionsJobSource,
-    IRemoveGranteeSubscriptionsJobSource,
     ISharingJob,
     ISharingJobSource,
     )
 from lp.registry.model.accesspolicy import reconcile_access_for_artifact
 from lp.registry.model.sharingjob import (
     RemoveBugSubscriptionsJob,
-    RemoveGranteeSubscriptionsJob,
     SharingJob,
     SharingJobDerived,
     SharingJobType,
@@ -97,18 +91,17 @@
 
     layer = DatabaseFunctionalLayer
 
-    def _makeJob(self, prod_name=None, grantee_name=None):
-        pillar = self.factory.makeProduct(name=prod_name)
-        grantee = self.factory.makePerson(name=grantee_name)
+    def _makeJob(self):
+        bug = self.factory.makeBug()
         requestor = self.factory.makePerson()
-        job = getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, requestor)
+        job = getUtility(IRemoveBugSubscriptionsJobSource).create(
+            requestor, bugs=[bug])
         return job
 
     def test_repr(self):
-        job = self._makeJob('prod', 'fred')
+        job = self._makeJob()
         self.assertEqual(
-            '<REMOVE_GRANTEE_SUBSCRIPTIONS job for Fred and Prod>',
+            '<REMOVE_BUG_SUBSCRIPTIONS job>',
             repr(job))
 
     def test_create_success(self):
@@ -132,26 +125,27 @@
         job_1 = self._makeJob()
         job_2 = self._makeJob()
         job_2.start()
-        jobs = list(RemoveGranteeSubscriptionsJob.iterReady())
+        jobs = list(RemoveBugSubscriptionsJob.iterReady())
         self.assertEqual(1, len(jobs))
         self.assertEqual(job_1, jobs[0])
 
     def test_log_name(self):
         # The log_name is the name of the implementing class.
         job = self._makeJob()
-        self.assertEqual('RemoveGranteeSubscriptionsJob', job.log_name)
+        self.assertEqual('RemoveBugSubscriptionsJob', job.log_name)
 
     def test_getOopsVars(self):
         # The pillar and grantee name are added to the oops vars.
-        pillar = self.factory.makeDistribution()
-        grantee = self.factory.makePerson()
+        bug = self.factory.makeBug()
         requestor = self.factory.makePerson()
-        job = getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, requestor)
+        job = getUtility(IRemoveBugSubscriptionsJobSource).create(
+            requestor, bugs=[bug])
         oops_vars = job.getOopsVars()
-        self.assertIs(True, len(oops_vars) > 4)
-        self.assertIn(('distro', pillar.name), oops_vars)
-        self.assertIn(('grantee', grantee.name), oops_vars)
+        self.assertIs(True, len(oops_vars) >= 3)
+        self.assertIn(
+            ('sharing_job_type',
+            'Remove subscriptions for users who can no longer access bugs.'),
+            oops_vars)
 
 
 def disable_trigger_fixture():
@@ -165,260 +159,6 @@
         })
 
 
-class RemoveGranteeSubscriptionsJobTestCase(TestCaseWithFactory):
-    """Test case for the RemoveGranteeSubscriptionsJob class."""
-
-    layer = CeleryJobLayer
-
-    def setUp(self):
-        self.useFixture(FeatureFixture({
-            'jobs.celery.enabled_classes':
-                'RemoveGranteeSubscriptionsJob',
-        }))
-        super(RemoveGranteeSubscriptionsJobTestCase, self).setUp()
-
-    def test_create(self):
-        # Create an instance of RemoveGranteeSubscriptionsJob that stores
-        # the information type and artifact information.
-        self.assertIs(
-            True,
-            IRemoveGranteeSubscriptionsJobSource.providedBy(
-                RemoveGranteeSubscriptionsJob))
-        self.assertEqual(
-            SharingJobType.REMOVE_GRANTEE_SUBSCRIPTIONS,
-            RemoveGranteeSubscriptionsJob.class_job_type)
-        pillar = self.factory.makeProduct()
-        grantee = self.factory.makePerson()
-        requestor = self.factory.makePerson()
-        bug = self.factory.makeBug(product=pillar)
-        branch = self.factory.makeBranch(product=pillar)
-        info_type = InformationType.USERDATA
-        job = getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, requestor, [info_type], [bug], [branch])
-        naked_job = removeSecurityProxy(job)
-        self.assertIsInstance(job, RemoveGranteeSubscriptionsJob)
-        self.assertEqual(pillar, job.pillar)
-        self.assertEqual(grantee, job.grantee)
-        self.assertEqual(requestor.id, naked_job.requestor_id)
-        self.assertContentEqual([info_type], naked_job.information_types)
-        self.assertContentEqual([bug.id], naked_job.bug_ids)
-        self.assertContentEqual([branch.unique_name], naked_job.branch_names)
-
-    def test_getErrorRecipients(self):
-        # The pillar owner and job requestor are the error recipients.
-        pillar = self.factory.makeDistribution()
-        grantee = self.factory.makePerson()
-        requestor = self.factory.makePerson()
-        job = getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, requestor)
-        expected_emails = [
-            format_address_for_person(person)
-            for person in (pillar.owner, requestor)]
-        self.assertContentEqual(
-            expected_emails, job.getErrorRecipients())
-
-    def test_create_no_pillar(self):
-        # Create an instance of RemoveGranteeSubscriptionsJob that stores
-        # the information type and artifact information but with no pillar.
-        grantee = self.factory.makePerson()
-        requestor = self.factory.makePerson()
-        job = getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            None, grantee, requestor)
-        naked_job = removeSecurityProxy(job)
-        self.assertIsInstance(job, RemoveGranteeSubscriptionsJob)
-        self.assertEqual(None, job.pillar)
-        self.assertEqual(grantee, job.grantee)
-        self.assertEqual(requestor.id, naked_job.requestor_id)
-        self.assertIn('all pillars', repr(job))
-        self.assertEqual(1, len(job.getErrorRecipients()))
-
-    def _make_subscribed_bug(self, grantee, product=None, distribution=None,
-                             information_type=InformationType.USERDATA):
-        owner = self.factory.makePerson()
-        bug = self.factory.makeBug(
-            owner=owner, product=product, distribution=distribution,
-            information_type=information_type)
-        with person_logged_in(owner):
-            bug.subscribe(grantee, owner)
-        # Subscribing grantee to bug creates an access grant so we need to
-        # revoke that for our test.
-        accessartifact_source = getUtility(IAccessArtifactSource)
-        accessartifact_grant_source = getUtility(IAccessArtifactGrantSource)
-        accessartifact_grant_source.revokeByArtifact(
-            accessartifact_source.find([bug]), [grantee])
-
-        return bug, owner
-
-    def test_unsubscribe_bugs(self):
-        # The requested bug subscriptions are removed.
-        pillar = self.factory.makeDistribution()
-        grantee = self.factory.makePerson()
-        owner = self.factory.makePerson()
-        bug, ignored = self._make_subscribed_bug(grantee, distribution=pillar)
-        getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, owner, bugs=[bug])
-        with block_on_job(self):
-            transaction.commit()
-        self.assertNotIn(
-            grantee, removeSecurityProxy(bug).getDirectSubscribers())
-
-    def test_unsubscribe_bugs_admin(self):
-        # Admins can see all bugs so no unsubscribe occurs.
-        pillar = self.factory.makeDistribution()
-        grantee = getUtility(ILaunchpadCelebrities).admin.teamowner
-        owner = self.factory.makePerson()
-        bug, ignored = self._make_subscribed_bug(grantee, distribution=pillar)
-        getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, owner, bugs=[bug])
-        with block_on_job(self):
-            transaction.commit()
-        self.assertIn(
-            grantee, removeSecurityProxy(bug).getDirectSubscribers())
-
-    def _make_subscribed_branch(self, pillar, grantee,
-                                information_type=None):
-        owner = self.factory.makePerson()
-        branch = self.factory.makeBranch(
-            owner=owner, product=pillar, information_type=information_type)
-        with person_logged_in(owner):
-            branch.subscribe(grantee,
-                BranchSubscriptionNotificationLevel.NOEMAIL, None,
-                CodeReviewNotificationLevel.NOEMAIL, owner)
-        return branch
-
-    def _assert_unsubscribe_pillar_artifacts_direct_bugs(self,
-                                                         pillar=None):
-        # All direct pillar bug subscriptions are removed.
-        grantee = self.factory.makePerson()
-
-        # Make some bugs subscribed to by grantee.
-        bug1, ignored = self._make_subscribed_bug(
-            grantee, product=pillar,
-            information_type=InformationType.EMBARGOEDSECURITY)
-        bug2, ignored = self._make_subscribed_bug(
-            grantee, product=pillar,
-            information_type=InformationType.USERDATA)
-
-        # Now run the job.
-        requestor = self.factory.makePerson()
-        getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, grantee, requestor)
-        with block_on_job(self):
-            transaction.commit()
-
-        self.assertNotIn(
-            grantee, removeSecurityProxy(bug1).getDirectSubscribers())
-        self.assertNotIn(
-            grantee, removeSecurityProxy(bug2).getDirectSubscribers())
-
-    def test_unsubscribe_pillar_artifacts_direct_bugs(self):
-        pillar = self.factory.makeProduct()
-        self._assert_unsubscribe_pillar_artifacts_direct_bugs(pillar)
-
-    def test_unsubscribe_artifacts_direct_bugs_unspecified_pillar(self):
-        self._assert_unsubscribe_pillar_artifacts_direct_bugs()
-
-    def _assert_unsubscribe_pillar_artifacts_indirect_bugs(self,
-                                                           pillar=None):
-        # Do not delete subscriptions to bugs a user has indirect access to
-        # because they belong to a team which has an artifact grant on the bug.
-
-        person_grantee = self.factory.makePerson(name='grantee')
-
-        # Make a bug the person_grantee is subscribed to.
-        bug1, ignored = self._make_subscribed_bug(
-            person_grantee, product=pillar,
-            information_type=InformationType.USERDATA)
-
-        # Make another bug and grant access to a team.
-        team_owner = self.factory.makePerson(name='teamowner')
-        team_grantee = self.factory.makeTeam(
-            owner=team_owner,
-            subscription_policy=TeamSubscriptionPolicy.RESTRICTED,
-            members=[person_grantee])
-        bug2, bug2_owner = self._make_subscribed_bug(
-            team_grantee, product=pillar,
-            information_type=InformationType.EMBARGOEDSECURITY)
-        # Add a subscription for the person_grantee.
-        with person_logged_in(bug2_owner):
-            bug2.subscribe(person_grantee, bug2_owner)
-
-        # Now run the job.
-        requestor = self.factory.makePerson()
-        getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, person_grantee, requestor)
-        with block_on_job(self):
-            transaction.commit()
-
-        # person_grantee is not longer subscribed to bug1.
-        self.assertNotIn(
-            person_grantee, removeSecurityProxy(bug1).getDirectSubscribers())
-        # person_grantee is still subscribed to bug2 because they have access
-        # via a team.
-        self.assertIn(
-            person_grantee, removeSecurityProxy(bug2).getDirectSubscribers())
-
-    def test_unsubscribe_pillar_artifacts_indirect_bugs(self):
-        pillar = self.factory.makeProduct()
-        self._assert_unsubscribe_pillar_artifacts_indirect_bugs(pillar)
-
-    def test_unsubscribe_artifacts_indirect_bugs_unspecified_pillar(self):
-        self._assert_unsubscribe_pillar_artifacts_indirect_bugs()
-
-    def _make_subscribed_bugs(self, person_grantee):
-        # Set up some bugs and subscribe the grantee.
-
-        owner = self.factory.makePerson(name='pillarowner')
-        pillar = self.factory.makeProduct(owner=owner)
-
-        # Make bugs the person_grantee is subscribed to.
-        bug1, ignored = self._make_subscribed_bug(
-            person_grantee, product=pillar,
-            information_type=InformationType.USERDATA)
-
-        bug2, ignored = self._make_subscribed_bug(
-            person_grantee, product=pillar,
-            information_type=InformationType.EMBARGOEDSECURITY)
-
-        return pillar, bug1, bug2
-
-    def test_unsubscribe_pillar_artifacts_specific_info_types(self):
-        # Only delete pillar artifacts of the specified info type.
-
-        person_grantee = self.factory.makePerson(name='grantee')
-
-        pillar, bug1, bug2 = self._make_subscribed_bugs(person_grantee)
-
-        # Now run the job, removing access to userdata artifacts.
-        getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, person_grantee, pillar.owner, [InformationType.USERDATA])
-        with block_on_job(self):
-            transaction.commit()
-
-        self.assertNotIn(
-            person_grantee, removeSecurityProxy(bug1).getDirectSubscribers())
-        self.assertIn(
-            person_grantee, removeSecurityProxy(bug2).getDirectSubscribers())
-
-    def test_unsubscribe_pillar_artifacts_admin_grantee(self):
-        # For admins, the job is effectively a no-op.
-
-        admin_grantee = getUtility(ILaunchpadCelebrities).admin.teamowner
-
-        pillar, bug1, bug2 = self._make_subscribed_bugs(admin_grantee)
-
-        # Now run the job, removing access to userdata artifacts.
-        getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-            pillar, admin_grantee, pillar.owner, [InformationType.USERDATA])
-        with block_on_job(self):
-            transaction.commit()
-
-        self.assertIn(
-            admin_grantee, removeSecurityProxy(bug1).getDirectSubscribers())
-        self.assertIn(
-            admin_grantee, removeSecurityProxy(bug2).getDirectSubscribers())
-
-
 class TestRunViaCron(TestCaseWithFactory):
     """Sharing jobs run via cron."""
 
@@ -462,19 +202,6 @@
         self.assertNotIn(
             grantee, removeSecurityProxy(bug).getDirectSubscribers())
 
-    def test_run_remove_grantee_subscriptions_cronscript(self):
-        # The cronscript is configured: schema-lazr.conf and security.cfg.
-        # The job runs correctly and the requested bug subscriptions are
-        # removed.
-
-        def create_job(distro, bug, grantee, owner):
-            return (
-                getUtility(IRemoveGranteeSubscriptionsJobSource).create(
-                    distro, grantee, owner, bugs=[bug]),
-                IRemoveGranteeSubscriptionsJobSource.getName())
-
-        self._assert_run_cronscript(create_job)
-
     def test_run_remove_bug_subscriptions_cronscript(self):
         # The cronscript is configured: schema-lazr.conf and security.cfg.
         # The job runs correctly and the requested bug subscriptions are

=== modified file 'lib/lp/services/config/schema-lazr.conf'
--- lib/lp/services/config/schema-lazr.conf	2012-06-13 01:05:42 +0000
+++ lib/lp/services/config/schema-lazr.conf	2012-06-14 03:51:25 +0000
@@ -1755,7 +1755,6 @@
     IPlainPackageCopyJobSource,
     IQuestionEmailJobSource,
     IRemoveBugSubscriptionsJobSource,
-    IRemoveGranteeSubscriptionsJobSource,
     ISevenDayCommercialExpirationJobSource,
     IThirtyDayCommercialExpirationJobSource
 
@@ -1763,6 +1762,7 @@
 module: lp.registry.interfaces.productjob
 dbuser: product-job
 crontab_group: MAIN
+>>>>>>> MERGE-SOURCE
 
 [IMembershipNotificationJobSource]
 # This section is used by cronscripts/process-job-source.py.
@@ -1794,12 +1794,6 @@
 dbuser: sharing-jobs
 crontab_group: MAIN
 
-[IRemoveGranteeSubscriptionsJobSource]
-# This section is used by cronscripts/process-job-source.py.
-module: lp.registry.interfaces.sharingjob
-dbuser: sharing-jobs
-crontab_group: MAIN
-
 [ISevenDayCommercialExpirationJobSource]
 module: lp.registry.interfaces.productjob
 dbuser: product-job