← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~julian-edwards/launchpad/delete-pcjs into lp:launchpad

 

Julian Edwards has proposed merging lp:~julian-edwards/launchpad/delete-pcjs into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~julian-edwards/launchpad/delete-pcjs/+merge/87696

Add IArchive.removeCopyNotification() and export it on the webservice.

It is a method to remove failed PackageCopyJobs for a PPA and is intended to be used by a separate branch that will show these failures on the PPA page and then allow the user to dismiss them by AJAX deletion of the job.
-- 
https://code.launchpad.net/~julian-edwards/launchpad/delete-pcjs/+merge/87696
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~julian-edwards/launchpad/delete-pcjs into lp:launchpad.
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg	2012-01-05 21:38:46 +0000
+++ database/schema/security.cfg	2012-01-05 22:39:38 +0000
@@ -235,7 +235,7 @@
 public.openidconsumernonce              = SELECT, INSERT, UPDATE
 public.openididentifier                 = SELECT, INSERT, UPDATE, DELETE
 public.packagebuild                     = DELETE
-public.packagecopyjob                   = SELECT, INSERT, UPDATE
+public.packagecopyjob                   = SELECT, INSERT, UPDATE, DELETE
 public.packagecopyrequest               = SELECT, INSERT, UPDATE
 public.packagediff                      = SELECT, INSERT, UPDATE, DELETE
 public.packageset                       = SELECT, INSERT, UPDATE, DELETE

=== modified file 'lib/lp/soyuz/browser/tests/test_archive_webservice.py'
--- lib/lp/soyuz/browser/tests/test_archive_webservice.py	2012-01-01 02:58:52 +0000
+++ lib/lp/soyuz/browser/tests/test_archive_webservice.py	2012-01-05 22:39:38 +0000
@@ -411,3 +411,35 @@
         ws_archive = self.wsObject(self.archive, user=self.person)
         publications = ws_archive.getPublishedBinaries(ordered=False)
         self.assertEqual(2, len(publications))
+
+
+class TestremoveCopyNotification(WebServiceTestCase):
+    """Test removeCopyNotification."""
+
+    def setUp(self):
+        super(TestremoveCopyNotification, self).setUp()
+        self.ws_version = 'devel'
+        self.person = self.factory.makePerson()
+        self.archive = self.factory.makeArchive(owner=self.person)
+
+    def test_removeCopyNotification(self):
+        distroseries = self.factory.makeDistroSeries()
+        source_archive = self.factory.makeArchive(distroseries.distribution)
+        requester = self.factory.makePerson()
+        source = getUtility(IPlainPackageCopyJobSource)
+        job = source.create(
+            package_name="foo", source_archive=source_archive,
+            target_archive=self.archive, target_distroseries=distroseries,
+            target_pocket=PackagePublishingPocket.RELEASE,
+            package_version="1.0-1", include_binaries=True,
+            requester=requester)
+        job.start()
+        job.fail()
+
+        ws_archive = self.wsObject(self.archive, user=self.person)
+        ws_archive.removeCopyNotification(job_id=job.id)
+        transaction.commit()
+
+        source = getUtility(IPlainPackageCopyJobSource)
+        self.assertEqual(
+            None, source.getIncompleteJobsForArchive(self.archive).any())

=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py	2012-01-01 02:58:52 +0000
+++ lib/lp/soyuz/interfaces/archive.py	2012-01-05 22:39:38 +0000
@@ -1435,6 +1435,22 @@
         :return: The `IArchiveSubscriber` that was created.
         """
 
+    @operation_parameters(job_id=Int())
+    @export_write_operation()
+    @operation_for_version("devel")
+    def removeCopyNotification(job_id):
+        """Remove a copy notification that's displayed on the +packages page.
+
+        Copy notifications are shown on the +packages page when a
+        `PlainPackageCopyJob` is in progress or failed.  Calling this
+        method will delete failed jobs so they no longer appear on the
+        page.
+
+        You need to have upload privileges on the PPA to use this.
+
+        :param job_id: The ID of the `PlainPackageCopyJob` to be removed.
+        """
+
 
 class IArchiveEdit(Interface):
     """Archive interface for operations restricted by edit privilege."""

=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py	2011-12-30 06:14:56 +0000
+++ lib/lp/soyuz/model/archive.py	2012-01-05 22:39:38 +0000
@@ -2022,6 +2022,17 @@
             return UbuntuOverridePolicy()
         return None
 
+    def removeCopyNotification(self, job_id):
+        """See `IArchive`."""
+        # Circular imports R us.
+        from lp.soyuz.model.packagecopyjob import PlainPackageCopyJob
+        pcj = PlainPackageCopyJob.get(job_id)
+        job = pcj.job
+        if job.status != JobStatus.FAILED:
+            raise AssertionError("Job is not failed")
+        Store.of(pcj.context).remove(pcj.context)
+        job.destroySelf()
+
 
 class ArchiveSet:
     implements(IArchiveSet)

=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py	2011-12-30 06:14:56 +0000
+++ lib/lp/soyuz/tests/test_archive.py	2012-01-05 22:39:38 +0000
@@ -2383,3 +2383,62 @@
         # not generate an error if the permission is None.
         ap_set = ArchivePermissionSet()
         ap_set._remove_permission(None)
+
+
+class TestRemovingCopyNotifications(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def makeJob(self):
+        distroseries = self.factory.makeDistroSeries()
+        archive1 = self.factory.makeArchive(distroseries.distribution)
+        archive2 = self.factory.makeArchive(distroseries.distribution)
+        requester = self.factory.makePerson()
+        source = getUtility(IPlainPackageCopyJobSource)
+        job = source.create(
+            package_name="foo", source_archive=archive1,
+            target_archive=archive2, target_distroseries=distroseries,
+            target_pocket=PackagePublishingPocket.RELEASE,
+            package_version="1.0-1", include_binaries=True,
+            requester=requester)
+        return (distroseries, archive1, archive2, requester, job)
+
+    def test_removeCopyNotification(self):
+        distroseries, archive1, archive2, requester, job = self.makeJob()
+        job.start()
+        job.fail()
+
+        with person_logged_in(archive2.owner):
+            archive2.removeCopyNotification(job.id)
+
+        source = getUtility(IPlainPackageCopyJobSource)
+        found_jobs = source.getIncompleteJobsForArchive(archive2)
+        self.assertEqual(None, found_jobs.any())
+
+    def test_removeCopyNotification_raises_for_not_failed(self):
+        distroseries, archive1, archive2, requester, job = self.makeJob()
+        
+        self.assertNotEqual(JobStatus.FAILED, job.status)
+        with person_logged_in(archive2.owner):
+            self.assertRaises(
+                AssertionError, archive2.removeCopyNotification, job.id)
+
+    def test_removeCopyNotification_raises_for_wrong_archive(self):
+        # If the job ID supplied is not for the context archive, an
+        # error should be raised.
+        distroseries, archive1, archive2, requester, job = self.makeJob()
+        job.start()
+        job.fail()
+
+        # Set up a second job in the other archive.
+        source = getUtility(IPlainPackageCopyJobSource)
+        job2 = source.create(
+            package_name="foo", source_archive=archive2,
+            target_archive=archive1, target_distroseries=distroseries,
+            target_pocket=PackagePublishingPocket.RELEASE,
+            package_version="1.0-1", include_binaries=True,
+            requester=requester)
+
+        with person_logged_in(archive2.owner):
+            self.assertRaises(
+                AssertionError, archive2.removeCopyNotification, job2.id)