launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32355
[Merge] ~enriqueesanchz/launchpad:add-bugtaskstatus-deferred into launchpad:master
Enrique Sánchez has proposed merging ~enriqueesanchz/launchpad:add-bugtaskstatus-deferred into launchpad:master.
Commit message:
Add DEFERRED to BugTaskStatus model
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~enriqueesanchz/launchpad/+git/launchpad/+merge/484235
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~enriqueesanchz/launchpad:add-bugtaskstatus-deferred into launchpad:master.
diff --git a/lib/canonical/launchpad/icing/css/colours.scss b/lib/canonical/launchpad/icing/css/colours.scss
index 937af46..58ea80b 100644
--- a/lib/canonical/launchpad/icing/css/colours.scss
+++ b/lib/canonical/launchpad/icing/css/colours.scss
@@ -204,7 +204,7 @@
}
}
- .statusINVALID, .statusWONTFIX, .statusDOESNOTEXIST, .status.statusOPINION {
+ .statusINVALID, .statusWONTFIX, .statusDOESNOTEXIST, .statusDEFERRED, .status.statusOPINION {
color: #555;
a {
@@ -301,7 +301,7 @@
}
}
- .statusEXPIRED, .statusINVALID, .statusWONTFIX, .statusDOESNOTEXIST, .statusOPINION {
+ .statusEXPIRED, .statusINVALID, .statusWONTFIX, .statusDOESNOTEXIST, .statusDEFERRED, .statusOPINION {
color: #464646;
background-color: #ddd;
diff --git a/lib/lp/bugs/browser/buglisting.py b/lib/lp/bugs/browser/buglisting.py
index f6aebfd..8adda0b 100644
--- a/lib/lp/bugs/browser/buglisting.py
+++ b/lib/lp/bugs/browser/buglisting.py
@@ -129,6 +129,7 @@ DISPLAY_BUG_STATUS_FOR_PATCHES = {
BugTaskStatus.CONFIRMED: True,
BugTaskStatus.TRIAGED: True,
BugTaskStatus.INPROGRESS: True,
+ BugTaskStatus.DEFERRED: True,
BugTaskStatus.FIXCOMMITTED: True,
BugTaskStatus.FIXRELEASED: False,
BugTaskStatus.UNKNOWN: False,
@@ -1529,7 +1530,7 @@ class BugTaskSearchListingView(LaunchpadFormView, FeedsMixin, BugsInfoMixin):
checked=term.value in default_values,
)
)
- return shortlist(widget_values, longest_expected=13)
+ return shortlist(widget_values, longest_expected=14)
def getStatusWidgetValues(self):
"""Return data used to render the status checkboxes."""
diff --git a/lib/lp/bugs/browser/bugtarget.py b/lib/lp/bugs/browser/bugtarget.py
index 199309d..d29d033 100644
--- a/lib/lp/bugs/browser/bugtarget.py
+++ b/lib/lp/bugs/browser/bugtarget.py
@@ -265,6 +265,7 @@ class FileBugViewBase(LaunchpadFormView):
BugTaskStatus.WONTFIX,
BugTaskStatus.INCOMPLETE,
BugTaskStatus.DOESNOTEXIST,
+ BugTaskStatus.DEFERRED,
],
)
cache.objects["bugtask_status_data"] = bugtask_status_data
diff --git a/lib/lp/bugs/browser/tests/person-bug-views.rst b/lib/lp/bugs/browser/tests/person-bug-views.rst
index 376bc71..ec08a1c 100644
--- a/lib/lp/bugs/browser/tests/person-bug-views.rst
+++ b/lib/lp/bugs/browser/tests/person-bug-views.rst
@@ -251,7 +251,7 @@ render the overview report.
>>> print(ubuntu_firefox_bugcounts["package_name"])
mozilla-firefox in Ubuntu
>>> print(ubuntu_firefox_bugcounts["package_search_url"]) # noqa
- http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.status=New&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
+ http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.status=New&field.status=Deferred&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
>>> print(ubuntu_firefox_bugcounts["open_bugs_count"])
1
@@ -263,11 +263,11 @@ render the overview report.
0
>>> print(ubuntu_firefox_bugcounts["open_bugs_url"]) # noqa
- http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.status=New&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
+ http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.status=New&field.status=Deferred&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
>>> print(ubuntu_firefox_bugcounts["critical_bugs_url"]) # noqa
- http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.importance=Critical&field.status=New&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
+ http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.importance=Critical&field.status=New&field.status=Deferred&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
>>> print(ubuntu_firefox_bugcounts["unassigned_bugs_url"]) # noqa
- http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?assignee_option=none&field.status=New&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
+ http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?assignee_option=none&field.status=New&field.status=Deferred&field.status=Incomplete&field.status=Confirmed&field.status=Triaged&field.status=In+Progress&field.status=Fix+Committed&search=Search
>>> print(ubuntu_firefox_bugcounts["inprogress_bugs_url"]) # noqa
http://bugs.launchpad.test/ubuntu/+source/mozilla-firefox?field.status=In+Progress&search=Search
diff --git a/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py b/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
index 769e610..17a673f 100644
--- a/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
+++ b/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
@@ -1105,6 +1105,7 @@ class TestFileBugRequestCache(TestCaseWithFactory):
BugTaskStatus.OPINION,
BugTaskStatus.WONTFIX,
BugTaskStatus.DOESNOTEXIST,
+ BugTaskStatus.DEFERRED,
BugTaskStatus.INCOMPLETE,
]
bugtask_status_data = []
diff --git a/lib/lp/bugs/browser/tests/test_bugtask.py b/lib/lp/bugs/browser/tests/test_bugtask.py
index 2a1eb92..8d665f0 100644
--- a/lib/lp/bugs/browser/tests/test_bugtask.py
+++ b/lib/lp/bugs/browser/tests/test_bugtask.py
@@ -1414,6 +1414,7 @@ class TestBugTaskEditViewStatusField(TestCaseWithFactory):
"Confirmed",
"Triaged",
"In Progress",
+ "Deferred",
"Fix Committed",
"Fix Released",
],
diff --git a/lib/lp/bugs/doc/bugtask-status-changes.rst b/lib/lp/bugs/doc/bugtask-status-changes.rst
index 0918240..8693ed9 100644
--- a/lib/lp/bugs/doc/bugtask-status-changes.rst
+++ b/lib/lp/bugs/doc/bugtask-status-changes.rst
@@ -5,9 +5,10 @@ Restrictions
------------
There are a few simple rules around who can change the status of a
-bug task. There are four statuses that can only be set by either
+bug task. There are five statuses that can only be set by either
the project maintainer, driver or bug supervisor:
+ * Deferred
* Won't Fix
* Does Not Exist
* Expired
@@ -20,6 +21,10 @@ the project maintainer, driver or bug supervisor:
>>> from lp.bugs.interfaces.bugtask import BugTaskStatus
>>> ignored = login_person(owner)
+ >>> bugtask.transitionToStatus(BugTaskStatus.DEFERRED, owner)
+ >>> print(bugtask.status.title)
+ Deferred
+
>>> bugtask.transitionToStatus(BugTaskStatus.WONTFIX, owner)
>>> print(bugtask.status.title)
Won't Fix
@@ -31,7 +36,7 @@ the project maintainer, driver or bug supervisor:
Regular users of Launchpad cannot transition a bug task to any of
these statuses.
-An additional restraint is added to Won't Fix and Does Not Exist.
+An additional restraint is added to Won't Fix, Does Not Exist and Deferred.
Only the product maintainer, driver or bug supervisor can change
from this status to any other status.
@@ -57,6 +62,14 @@ from this status to any other status.
...
lp.bugs.interfaces.bugtask.UserCannotEditBugTaskStatus: ...
+ >>> bugtask.transitionToStatus(BugTaskStatus.DEFERRED, owner)
+ >>> print(bugtask.status.title)
+ Deferred
+ >>> bugtask.transitionToStatus(BugTaskStatus.CONFIRMED, user)
+ Traceback (most recent call last):
+ ...
+ lp.bugs.interfaces.bugtask.UserCannotEditBugTaskStatus: ...
+
This is fully tested in
lp.bugs.tests.test_bugtask_status.TestBugTaskStatusSetting.
diff --git a/lib/lp/bugs/interfaces/bugtask.py b/lib/lp/bugs/interfaces/bugtask.py
index 3864b76..f9be6c0 100644
--- a/lib/lp/bugs/interfaces/bugtask.py
+++ b/lib/lp/bugs/interfaces/bugtask.py
@@ -241,6 +241,15 @@ class BugTaskStatus(DBEnumeratedType):
""",
)
+ DEFERRED = DBItem(
+ 23,
+ """
+ Deferred
+
+ Fixing has been deferred.
+ """,
+ )
+
FIXCOMMITTED = DBItem(
25,
"""
@@ -346,6 +355,7 @@ class BugTaskStatusSearchDisplay(DBEnumeratedType):
UNRESOLVED_BUGTASK_STATUSES = (
BugTaskStatus.NEW,
+ BugTaskStatus.DEFERRED,
BugTaskStatus.INCOMPLETE,
BugTaskStatus.CONFIRMED,
BugTaskStatus.TRIAGED,
@@ -374,6 +384,7 @@ RESOLVED_BUGTASK_STATUSES = (
BUG_SUPERVISOR_BUGTASK_STATUSES = (
BugTaskStatus.WONTFIX,
+ BugTaskStatus.DEFERRED,
BugTaskStatus.EXPIRED,
BugTaskStatus.TRIAGED,
BugTaskStatus.DOESNOTEXIST,
diff --git a/lib/lp/bugs/interfaces/bugtasksearch.py b/lib/lp/bugs/interfaces/bugtasksearch.py
index c78d1cc..83253c6 100644
--- a/lib/lp/bugs/interfaces/bugtasksearch.py
+++ b/lib/lp/bugs/interfaces/bugtasksearch.py
@@ -493,6 +493,7 @@ DEFAULT_SEARCH_BUGTASK_STATUSES = (
BugTaskStatusSearch.CONFIRMED,
BugTaskStatusSearch.TRIAGED,
BugTaskStatusSearch.INPROGRESS,
+ BugTaskStatusSearch.DEFERRED,
BugTaskStatusSearch.FIXCOMMITTED,
)
diff --git a/lib/lp/bugs/interfaces/tests/test_bugtask.py b/lib/lp/bugs/interfaces/tests/test_bugtask.py
index 3e5981a..f804e75 100644
--- a/lib/lp/bugs/interfaces/tests/test_bugtask.py
+++ b/lib/lp/bugs/interfaces/tests/test_bugtask.py
@@ -53,6 +53,7 @@ class TestFunctions(TestCase):
BugTaskStatus.TRIAGED: BugTaskStatus.TRIAGED,
BugTaskStatus.UNKNOWN: BugTaskStatus.UNKNOWN,
BugTaskStatus.WONTFIX: BugTaskStatus.WONTFIX,
+ BugTaskStatus.DEFERRED: BugTaskStatus.DEFERRED,
}
observed = {
status: normalize_bugtask_status(status)
@@ -80,6 +81,7 @@ class TestFunctions(TestCase):
BugTaskStatusSearch.OPINION: BugTaskStatus.OPINION,
BugTaskStatusSearch.TRIAGED: BugTaskStatus.TRIAGED,
BugTaskStatusSearch.WONTFIX: BugTaskStatus.WONTFIX,
+ BugTaskStatusSearch.DEFERRED: BugTaskStatus.DEFERRED,
}
observed = {
status: normalize_bugtask_status(status)
@@ -112,6 +114,7 @@ class TestFunctions(TestCase):
BugTaskStatusSearchDisplay.OPINION: BugTaskStatus.OPINION,
BugTaskStatusSearchDisplay.TRIAGED: BugTaskStatus.TRIAGED,
BugTaskStatusSearchDisplay.WONTFIX: BugTaskStatus.WONTFIX,
+ BugTaskStatusSearchDisplay.DEFERRED: BugTaskStatus.DEFERRED,
}
observed = {
status: normalize_bugtask_status(status)
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index 2d9845e..799c8cf 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -1026,9 +1026,11 @@ class BugTask(StormBase):
return False
elif (
self.status == BugTaskStatus.WONTFIX
+ or self.status == BugTaskStatus.DEFERRED
or self.status == BugTaskStatus.DOESNOTEXIST
):
- # Only bug supervisors can switch away from WONTFIX and DNE.
+ # Only bug supervisors can switch away from WONTFIX,
+ # DEFERRED and DNE.
return False
# Non-supervisors can transition to non-supervisor statuses.
return new_status not in BUG_SUPERVISOR_BUGTASK_STATUSES
diff --git a/lib/lp/bugs/model/tests/test_bugtask.py b/lib/lp/bugs/model/tests/test_bugtask.py
index f607999..2eed994 100644
--- a/lib/lp/bugs/model/tests/test_bugtask.py
+++ b/lib/lp/bugs/model/tests/test_bugtask.py
@@ -2313,7 +2313,33 @@ class TestConjoinedBugTasks(TestCaseWithFactory):
self.assertEqual("trunk", alsa_utils.development_focus.name)
current_series_netapplet_task.transitionToStatus(
- BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user
+ BugTaskStatus.DEFERRED, getUtility(ILaunchpadCelebrities).admin
+ )
+
+ # The attributes were synced with the generic task.
+ self.assertEqual(
+ "Deferred", current_series_netapplet_task.status.title
+ )
+
+ self.assertEqual(
+ current_series_netapplet_task.date_assigned,
+ generic_netapplet_task.date_assigned,
+ )
+ self.assertEqual(
+ current_series_netapplet_task.date_confirmed,
+ generic_netapplet_task.date_confirmed,
+ )
+ self.assertEqual(
+ current_series_netapplet_task.date_inprogress,
+ generic_netapplet_task.date_inprogress,
+ )
+ self.assertEqual(
+ current_series_netapplet_task.date_closed,
+ generic_netapplet_task.date_closed,
+ )
+ # Only admin can transition from BugTaskStatus.DEFERRED
+ current_series_netapplet_task.transitionToStatus(
+ BugTaskStatus.FIXRELEASED, getUtility(ILaunchpadCelebrities).admin
)
self.assertIsInstance(generic_netapplet_task.date_left_new, datetime)
diff --git a/lib/lp/bugs/model/tests/test_bugtask_status.py b/lib/lp/bugs/model/tests/test_bugtask_status.py
index 0ad43a2..fb0f2e6 100644
--- a/lib/lp/bugs/model/tests/test_bugtask_status.py
+++ b/lib/lp/bugs/model/tests/test_bugtask_status.py
@@ -43,6 +43,12 @@ class TestBugTaskStatusTransitionForUser(TestCaseWithFactory):
self.assertRaises(
UserCannotEditBugTaskStatus,
self.task.transitionToStatus,
+ BugTaskStatus.DEFERRED,
+ self.user,
+ )
+ self.assertRaises(
+ UserCannotEditBugTaskStatus,
+ self.task.transitionToStatus,
BugTaskStatus.DOESNOTEXIST,
self.user,
)
@@ -87,6 +93,18 @@ class TestBugTaskStatusTransitionForUser(TestCaseWithFactory):
self.user,
)
+ def test_user_cannot_unset_deferred_status(self):
+ # A regular user should not be able to transition a bug away
+ # from Deferred
+ removeSecurityProxy(self.task)._status = BugTaskStatus.DEFERRED
+ with person_logged_in(self.user):
+ self.assertRaises(
+ UserCannotEditBugTaskStatus,
+ self.task.transitionToStatus,
+ BugTaskStatus.CONFIRMED,
+ self.user,
+ )
+
def test_user_cannot_unset_does_not_exist_status(self):
# A regular user should not be able to transition a bug away
# from Does not exist.
@@ -119,6 +137,10 @@ class TestBugTaskStatusTransitionForUser(TestCaseWithFactory):
False,
)
self.assertEqual(
+ self.task.canTransitionToStatus(BugTaskStatus.DEFERRED, self.user),
+ False,
+ )
+ self.assertEqual(
self.task.canTransitionToStatus(
BugTaskStatus.DOESNOTEXIST, self.user
),
@@ -183,6 +205,15 @@ class TestBugTaskStatusTransitionForUser(TestCaseWithFactory):
False,
)
+ def test_user_canTransitionToStatus_from_deferred(self):
+ # A regular user cannot transition away from Deferred
+ # so canTransitionToStatus should return False.
+ removeSecurityProxy(self.task)._status = BugTaskStatus.DEFERRED
+ self.assertEqual(
+ self.task.canTransitionToStatus(BugTaskStatus.NEW, self.user),
+ False,
+ )
+
def test_user_canTransitionToStatus_from_doesnotexist(self):
# A regular user cannot transition away from Does Not Exist,
# so canTransitionToStatus should return False.
@@ -324,6 +355,8 @@ class TestBugTaskStatusTransitionForPrivilegedUserBase:
with person_logged_in(self.person):
self.task.transitionToStatus(BugTaskStatus.WONTFIX, self.person)
self.assertEqual(self.task.status, BugTaskStatus.WONTFIX)
+ self.task.transitionToStatus(BugTaskStatus.DEFERRED, self.person)
+ self.assertEqual(self.task.status, BugTaskStatus.DEFERRED)
self.task.transitionToStatus(
BugTaskStatus.DOESNOTEXIST, self.person
)
@@ -360,6 +393,13 @@ class TestBugTaskStatusTransitionForPrivilegedUserBase:
self.task.transitionToStatus(BugTaskStatus.CONFIRMED, self.person)
self.assertEqual(self.task.status, BugTaskStatus.CONFIRMED)
+ def test_privileged_user_can_unset_deferred_status(self):
+ # Privileged users can transition away from Deferred
+ removeSecurityProxy(self.task)._status = BugTaskStatus.DEFERRED
+ with person_logged_in(self.person):
+ self.task.transitionToStatus(BugTaskStatus.CONFIRMED, self.person)
+ self.assertEqual(self.task.status, BugTaskStatus.CONFIRMED)
+
def test_privileged_user_can_unset_does_not_exist_status(self):
# Privileged users can transition away from Does Not Exist.
removeSecurityProxy(self.task)._status = BugTaskStatus.DOESNOTEXIST
@@ -386,6 +426,12 @@ class TestBugTaskStatusTransitionForPrivilegedUserBase:
)
self.assertEqual(
self.task.canTransitionToStatus(
+ BugTaskStatus.DEFERRED, self.person
+ ),
+ True,
+ )
+ self.assertEqual(
+ self.task.canTransitionToStatus(
BugTaskStatus.DOESNOTEXIST, self.person
),
True,
@@ -458,6 +504,15 @@ class TestBugTaskStatusTransitionForPrivilegedUserBase:
True,
)
+ def test_privileged_user_canTransitionToStatus_from_deferred(self):
+ # A privileged user can transition away from Deferred, so
+ # canTransitionToStatus should return True.
+ removeSecurityProxy(self.task)._status = BugTaskStatus.DEFERRED
+ self.assertEqual(
+ self.task.canTransitionToStatus(BugTaskStatus.NEW, self.person),
+ True,
+ )
+
def test_privileged_user_canTransitionToStatus_from_doesnotexist(self):
# A privileged user can transition away from Does Not Exist, so
# canTransitionToStatus should return True.
diff --git a/lib/lp/bugs/scripts/uct/models.py b/lib/lp/bugs/scripts/uct/models.py
index 418f074..910881b 100644
--- a/lib/lp/bugs/scripts/uct/models.py
+++ b/lib/lp/bugs/scripts/uct/models.py
@@ -454,8 +454,7 @@ class CVE:
UCTRecord.PackageStatus.DOES_NOT_EXIST: BugTaskStatus.DOESNOTEXIST,
UCTRecord.PackageStatus.RELEASED: BugTaskStatus.FIXRELEASED,
UCTRecord.PackageStatus.NOT_AFFECTED: BugTaskStatus.INVALID,
- # we don't have a corresponding BugTaskStatus for this yet
- # PackageStatus.DEFERRED: ...,
+ UCTRecord.PackageStatus.DEFERRED: BugTaskStatus.DEFERRED,
UCTRecord.PackageStatus.NEEDED: BugTaskStatus.NEW,
UCTRecord.PackageStatus.PENDING: BugTaskStatus.FIXCOMMITTED,
}
diff --git a/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.rst b/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.rst
index fa5725c..aa9cbec 100644
--- a/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.rst
+++ b/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.rst
@@ -58,6 +58,11 @@ those statuses are not shown in the UI:
...
zope.testbrowser.browser.ItemNotFoundError: Does Not Exist
+ >>> status_control.displayValue = ["Deferred"]
+ Traceback (most recent call last):
+ ...
+ zope.testbrowser.browser.ItemNotFoundError: Deferred
+
Bug Supervisor
--------------
diff --git a/lib/lp/bugs/tests/bugs-emailinterface.rst b/lib/lp/bugs/tests/bugs-emailinterface.rst
index 75daf6a..7eaf399 100644
--- a/lib/lp/bugs/tests/bugs-emailinterface.rst
+++ b/lib/lp/bugs/tests/bugs-emailinterface.rst
@@ -1617,7 +1617,7 @@ Invalid status:
...
The 'status' command expects any of the following arguments:
new, incomplete, opinion, invalid, wontfix, expired, confirmed, triaged,
- inprogress, fixcommitted, fixreleased, doesnotexist
+ inprogress, deferred, fixcommitted, fixreleased, doesnotexist
<BLANKLINE>
For example:
<BLANKLINE>
diff --git a/lib/lp/registry/browser/tests/test_productseries_views.py b/lib/lp/registry/browser/tests/test_productseries_views.py
index f43eb49..8082157 100644
--- a/lib/lp/registry/browser/tests/test_productseries_views.py
+++ b/lib/lp/registry/browser/tests/test_productseries_views.py
@@ -252,6 +252,7 @@ class TestProductSeriesStatus(TestCaseWithFactory):
(BugTaskStatus.CONFIRMED, 1),
(BugTaskStatus.TRIAGED, 1),
(BugTaskStatus.INPROGRESS, 1),
+ (BugTaskStatus.DEFERRED, 1),
(BugTaskStatus.FIXCOMMITTED, 1),
(BugTaskStatus.FIXRELEASED, 1),
(BugTaskStatus.DOESNOTEXIST, 1),