← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~gmb/launchpad/expose-level-bug-704685 into lp:launchpad

 

Graham Binns has proposed merging lp:~gmb/launchpad/expose-level-bug-704685 into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  #704685 Expose BugSubscription.bug_notification_level in the API
  https://bugs.launchpad.net/bugs/704685

For more details, see:
https://code.launchpad.net/~gmb/launchpad/expose-level-bug-704685/+merge/46829

This branch exposes BugNotificationLevel via the WebService API. It also
exports the level parameter of IBug.subscribe() so that people can
subscribe at a given BugNotificationLevel.

== lib/canonical/launchpad/components/apihelpers.py ==

 - With Leonard's help I've added a helper to allow us to patch the
   vocabulary of a Choice param when exported via the API.

== lib/canonical/launchpad/interfaces/_schema_circular_imports.py ==

 - I've added some circular-import-avoidance code here. If it weren't
   for the CI problem I would have used copy_field to copy
   IBugSubscription['bug_notification_level'].

== lib/lp/bugs/interfaces/bug.py ==

 - I've added the declaration of level as an operation parameter for
   IBug.subscribe().

== lib/lp/bugs/interfaces/bugsubscription.py ==

 - I've exported IBugSubscription.bug_notification_level.

== lib/lp/bugs/stories/webservice/xx-bug.txt ==

 - I've updated the existing webservice tests to cover the new
   functionality.
-- 
https://code.launchpad.net/~gmb/launchpad/expose-level-bug-704685/+merge/46829
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gmb/launchpad/expose-level-bug-704685 into lp:launchpad.
=== modified file 'lib/canonical/launchpad/components/apihelpers.py'
--- lib/canonical/launchpad/components/apihelpers.py	2010-04-22 04:34:39 +0000
+++ lib/canonical/launchpad/components/apihelpers.py	2011-01-19 21:06:45 +0000
@@ -16,6 +16,7 @@
 __all__ = [
     'patch_entry_return_type',
     'patch_choice_parameter_type',
+    'patch_choice_vocabulary',
     'patch_collection_property',
     'patch_collection_return_type',
     'patch_plain_parameter_type',
@@ -111,3 +112,17 @@
     :param collection_type: The `Collection` type.
     """
     exported_class[property_name].value_type.schema = collection_type
+
+
+def patch_choice_vocabulary(exported_class, method_name, param_name,
+                            vocabulary):
+    """Set the `Vocabulary` for a `Choice` parameter for a given method.
+
+    :param exported_class: The class containing the property.
+    :param property_name: The name of the property whose type you need
+        to patch.
+    :param vocabulary: The `Vocabulary` type.
+    """
+    exported_class[method_name].queryTaggedValue(
+        LAZR_WEBSERVICE_EXPORTED)[
+            'params'][param_name].vocabulary = vocabulary

=== modified file 'lib/canonical/launchpad/interfaces/_schema_circular_imports.py'
--- lib/canonical/launchpad/interfaces/_schema_circular_imports.py	2010-12-22 07:53:52 +0000
+++ lib/canonical/launchpad/interfaces/_schema_circular_imports.py	2011-01-19 21:06:45 +0000
@@ -20,6 +20,7 @@
 
 from canonical.launchpad.components.apihelpers import (
     patch_choice_parameter_type,
+    patch_choice_vocabulary,
     patch_collection_property,
     patch_collection_return_type,
     patch_entry_return_type,
@@ -80,6 +81,7 @@
     HWBus,
     IHWSubmission,
     )
+from lp.registry.enum import BugNotificationLevel
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distributionmirror import IDistributionMirror
 from lp.registry.interfaces.distributionsourcepackage import (
@@ -486,6 +488,9 @@
     IBug, 'getNominationFor', 'target', IBugTarget)
 patch_plain_parameter_type(
     IBug, 'getNominations', 'target', IBugTarget)
+patch_choice_vocabulary(
+    IBug, 'subscribe', 'level', BugNotificationLevel)
+
 
 # IFrontPageBugAddForm
 patch_reference_property(IFrontPageBugAddForm, 'bugtarget', IBugTarget)

=== modified file 'lib/lp/bugs/interfaces/bug.py'
--- lib/lp/bugs/interfaces/bug.py	2010-11-04 02:32:16 +0000
+++ lib/lp/bugs/interfaces/bug.py	2011-01-19 21:06:45 +0000
@@ -24,6 +24,7 @@
 
 from textwrap import dedent
 
+from lazr.enum import DBEnumeratedType
 from lazr.lifecycle.snapshot import doNotSnapshot
 from lazr.restful.declarations import (
     call_with,
@@ -435,7 +436,13 @@
     # subscription-related methods
 
     @operation_parameters(
-        person=Reference(IPerson, title=_('Person'), required=True))
+        person=Reference(IPerson, title=_('Person'), required=True),
+        # level actually uses BugNotificationLevel as its vocabulary,
+        # but due to circular import problems we fix that in
+        # _schema_circular_imports.py rather than here.
+        level=Choice(
+            vocabulary=DBEnumeratedType, required=False,
+            title=_('Level')))
     @call_with(subscribed_by=REQUEST_USER, suppress_notify=False)
     @export_write_operation()
     def subscribe(person, subscribed_by, suppress_notify=True, level=None):

=== modified file 'lib/lp/bugs/interfaces/bugsubscription.py'
--- lib/lp/bugs/interfaces/bugsubscription.py	2010-09-09 21:00:54 +0000
+++ lib/lp/bugs/interfaces/bugsubscription.py	2011-01-19 21:06:45 +0000
@@ -48,13 +48,14 @@
     bug = exported(Reference(
         IBug, title=_("Bug"), required=True, readonly=True))
     bugID = Int(title=u"The bug id.", readonly=True)
-    bug_notification_level = Choice(
-        title=_("Bug notification level"), required=True,
-        vocabulary=BugNotificationLevel,
-        default=BugNotificationLevel.COMMENTS,
-        description=_(
-            "The volume and type of bug notifications "
-            "this subscription will generate."))
+    bug_notification_level = exported(
+        Choice(
+            title=_("Bug notification level"), required=True,
+            vocabulary=BugNotificationLevel,
+            default=BugNotificationLevel.COMMENTS,
+            description=_(
+                "The volume and type of bug notifications "
+                "this subscription will generate.")))
     date_created = exported(
         Datetime(title=_('Date subscribed'), required=True, readonly=True))
     subscribed_by = exported(PersonChoice(

=== modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt'
--- lib/lp/bugs/stories/webservice/xx-bug.txt	2011-01-17 21:51:09 +0000
+++ lib/lp/bugs/stories/webservice/xx-bug.txt	2011-01-19 21:06:45 +0000
@@ -825,6 +825,7 @@
   ...     pprint_entry(entry)
   ...     print
   bug_link: u'http://.../bugs/1'
+  bug_notification_level: u'Discussion'
   date_created: u'2006-10-16T18:31:43.156104+00:00'
   person_link: u'http://.../~name12'
   resource_type_link: u'http://.../#bug_subscription'
@@ -844,6 +845,7 @@
   ...     subscription_entries[1]['self_link']).jsonBody()
   >>> pprint_entry(subscription)
   bug_link: u'http://.../bugs/1'
+  bug_notification_level: u'Discussion'
   date_created: u'2006-10-16T18:31:43.154816+00:00'
   person_link: u'http://.../~stevea'
   resource_type_link: u'http://.../#bug_subscription'
@@ -874,6 +876,21 @@
     ...     bug_one['self_link'], 'unsubscribe')
     HTTP/1.1 200 Ok...
 
+An individual can subscribe themself at a given BugNotificationLevel.
+
+    >>> new_subscription = webservice.named_post(
+    ...     bug_one['self_link'], 'subscribe',
+    ...     person=webservice.getAbsoluteUrl('/~cprov'),
+    ...     level=u"Details").jsonBody()
+    >>> pprint_entry(new_subscription)
+    bug_link: u'.../bugs/1'
+    bug_notification_level: u'Discussion'
+    date_created: u'...'
+    person_link: u'...'
+    resource_type_link: u'...'
+    self_link: u'...'
+    subscribed_by_link: u'...'
+
 If one person tries to unsubscribe another individual, the web
 service will return an unauthorized error.