← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~gary/launchpad/bug740631 into lp:launchpad/db-devel

 

Gary Poster has proposed merging lp:~gary/launchpad/bug740631 into lp:launchpad/db-devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #740631 in Launchpad itself: "mute and umute bug subscription doesn't change icon"
  https://bugs.launchpad.net/launchpad/+bug/740631

For more details, see:
https://code.launchpad.net/~gary/launchpad/bug740631/+merge/63251

Despite the fact that the name of this branch is bug740631 (adding distinguishable icons for mute and unmute), the main point of it is to polish up the mute/unmute changes before they go live to everyone next week.  We expected them to be addressed by our rework of these bits for bug 772754, but that's not quite ready yet.  Therefore, this branch spends a bit of time polishing what we have.

This addresses the following issues identified by Danilo in his qa of the work for bug 772763:

> - "Unmute" links keeps pointing to "+subscribe" instead of "+mute" (+mute page was changed to
> support both muting/unmuting, and doesn't redirect to +subscribe when bug mail is muted anymore);
> this means that people will be sent to the wrong page if they have no JS

This was a simple change in lib/lp/bugs/browser/bug.py, in the code that draws the link.  It also adds the new mute/unmute icons.

> - When there is a mute on a bug, but no subscription, clicking on "Subscribe" fails to pop-up the
> window; also, going to +subscribe page renders an empty form which doesn't work in that case (this
> two are likely related)

I addressed this by adding an option within lib/lp/bugs/browser/bugsubscription.py to "unmute and subscribe", which means that there is actually something to draw, in addition to being a reasonable option for a user to see when they click on "subscribe".

> - When one tries to "Subscribe" originally (or unmute when they have an old subscription, or
> unsubscribe yourself), subscription overlay pop-up stays loaded when you click on check-mark to
> apply the action even though the action succeeds; this is especially bad if there's an error since
> then the error pop-up is below the subscription overlay

I found this to be tricky to address with the existing JS, but the changes in lib/lp/bugs/javascript/bugtask_index_portlets.js seem to do the right thing.

I also addressed the following problems.

- Anonymous users would get an OOPS when they visited a bug page if the feature flag was turned on for them.

- test_unmute_unmutes was getting a cached value for self.bug.isSubscribed, which did not actually demonstrate the desired end state. I changed the code to use the pattern elsewhere in the file.  An alternative approach that works is to commit the transaction, but I thought this was preferable.

- In some cases, two instances of the user's name would be added to the "directly subscribed" display.

- In some cases, an instance of the user's name would turn permanently green after a success "flash".

- +subscriptions had not been modified to take advantage of the new mute functionality.  I did so by changing options.

- The test for the ellipsis hack in lib/lp/registry/javascript/tests/test_structural_subscription.js did not work in webkit-based browsers.

In addition to that, I added in the new mute/unmute icons Huw provided for bug 740631.

Thank you,

Gary
-- 
https://code.launchpad.net/~gary/launchpad/bug740631/+merge/63251
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gary/launchpad/bug740631 into lp:launchpad/db-devel.
=== modified file 'lib/canonical/launchpad/icing/sprite.css.in'
--- lib/canonical/launchpad/icing/sprite.css.in	2011-03-23 01:05:54 +0000
+++ lib/canonical/launchpad/icing/sprite.css.in	2011-06-02 15:51:45 +0000
@@ -45,6 +45,14 @@
     background-image: url(/@@/yes.png); /* sprite-ref: icon-sprites */
     background-repeat: no-repeat;
     }
+.mute {
+    background-image: url(/@@/mute.png); /* sprite-ref: icon-sprites */
+    background-repeat: no-repeat;
+    }
+.unmute {
+    background-image: url(/@@/unmute.png); /* sprite-ref: icon-sprites */
+    background-repeat: no-repeat;
+    }
 .crowd {
     background-image: url(/@@/crowd.png); /* sprite-ref: icon-sprites */
     background-repeat: no-repeat;

=== added file 'lib/canonical/launchpad/images/mute.png'
Binary files lib/canonical/launchpad/images/mute.png	1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/mute.png	2011-06-02 15:51:45 +0000 differ
=== added file 'lib/canonical/launchpad/images/unmute.png'
Binary files lib/canonical/launchpad/images/unmute.png	1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/unmute.png	2011-06-02 15:51:45 +0000 differ
=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py	2011-05-20 14:48:53 +0000
+++ lib/lp/bugs/browser/bug.py	2011-06-02 15:51:45 +0000
@@ -285,13 +285,13 @@
         user = getUtility(ILaunchBag).user
         if self.context.bug.isMuted(user):
             text = "Unmute bug mail"
-            link = "+subscribe"
+            icon = 'unmute'
         else:
             text = "Mute bug mail"
-            link = "+mute"
+            icon = 'mute'
 
         return Link(
-            link, text, icon='remove', summary=(
+            '+mute', text, icon=icon, summary=(
                 "Mute this bug so that you will not receive emails "
                 "about it."))
 
@@ -537,7 +537,7 @@
     def user_should_see_mute_link(self):
         """Return True if the user should see the Mute link."""
         if features.getFeatureFlag('malone.advanced-subscriptions.enabled'):
-            user_is_subscribed = (
+            user_is_subscribed = self.user is not None and (
                 self.context.isMuted(self.user) or
                 self.context.isSubscribed(self.user) or
                 self.context.isSubscribedToDupes(self.user) or

=== modified file 'lib/lp/bugs/browser/bugsubscription.py'
--- lib/lp/bugs/browser/bugsubscription.py	2011-05-24 19:33:23 +0000
+++ lib/lp/bugs/browser/bugsubscription.py	2011-06-02 15:51:45 +0000
@@ -275,10 +275,18 @@
                         'unsubscribe <a href="%s">%s</a> from this bug' % (
                             canonical_url(person),
                             cgi.escape(person.displayname))))
-        if not self_subscribed and not is_really_muted:
-            subscription_terms.insert(0,
-                SimpleTerm(
-                    self.user, self.user.name, 'subscribe me to this bug'))
+        if not self_subscribed:
+            if not is_really_muted:
+                subscription_terms.insert(0,
+                    SimpleTerm(
+                        self.user, self.user.name,
+                        'subscribe me to this bug'))
+            elif not self.user_is_subscribed_directly:
+                subscription_terms.insert(0,
+                    SimpleTerm(
+                        'update-subscription', 'update-subscription',
+                        'unmute bug mail from this bug and subscribe me to '
+                        'this bug'))
 
         # Add punctuation to the list of terms.
         if len(subscription_terms) > 1:
@@ -289,7 +297,7 @@
 
         subscription_vocabulary = SimpleVocabulary(subscription_terms)
         if (self._use_advanced_features and
-            self.user_is_subscribed_directly):
+            (self.user_is_subscribed_directly or self.user_is_muted)):
             default_subscription_value = self._update_subscription_term.value
         else:
             default_subscription_value = (
@@ -319,7 +327,7 @@
         if self._use_advanced_features:
             self.widgets['bug_notification_level'].widget_class = (
                 'bug-notification-level-field')
-            if self._subscriber_count_for_current_user == 0:
+            if (len(self.form_fields['subscription'].field.vocabulary)==1):
                 # We hide the subscription widget if the user isn't
                 # subscribed, since we know who the subscriber is and we
                 # don't need to present them with a single radio button.
@@ -330,9 +338,7 @@
                 # subscribe theirself or unsubscribe their team.
                 self.widgets['subscription'].visible = True
 
-            if (self.user_is_subscribed_to_dupes_only or
-                (self._use_advanced_features and self.user_is_muted and
-                 not self.user_is_subscribed)):
+            if self.user_is_subscribed_to_dupes_only:
                 # If the user is subscribed via a duplicate but is not
                 # directly subscribed, we hide the
                 # bug_notification_level field, since it's not used.

=== modified file 'lib/lp/bugs/browser/tests/test_bug_views.py'
--- lib/lp/bugs/browser/tests/test_bug_views.py	2011-05-24 19:33:23 +0000
+++ lib/lp/bugs/browser/tests/test_bug_views.py	2011-06-02 15:51:45 +0000
@@ -203,6 +203,16 @@
                     self._hasCSSClass(html, 'mute-link-container', 'hidden'),
                     'No "hidden" CSS class in mute-link-container.')
 
+    def test_mute_subscription_link_not_rendered_for_anonymous(self):
+        # If a person is not already subscribed to a bug in some way,
+        # the mute link will not be displayed to them.
+        with FeatureFixture({self.feature_flag_1: 'on'}):
+            view = create_initialized_view(
+                self.bug, name="+portlet-subscription")
+            self.assertFalse(view.user_should_see_mute_link)
+            html = view.render()
+            self.assertFalse('mute_subscription' in html)
+
     def test_mute_subscription_link_shown_if_muted(self):
         # If a person is muted but not otherwise subscribed, they should still
         # see the (un)mute link.

=== modified file 'lib/lp/bugs/browser/tests/test_bugsubscription_views.py'
--- lib/lp/bugs/browser/tests/test_bugsubscription_views.py	2011-05-24 19:33:23 +0000
+++ lib/lp/bugs/browser/tests/test_bugsubscription_views.py	2011-06-02 15:51:45 +0000
@@ -227,7 +227,7 @@
                 self.assertFalse(
                     harness.view.widgets['bug_notification_level'].visible)
 
-    def test_muted_subs_have_unmute_option(self):
+    def test_muted_subs_have_subscribe_option_and_unmute_option(self):
         # If a user has a muted subscription, but no previous
         # direct bug subscription, the BugSubscriptionSubscribeSelfView's
         # subscription field will show an "Unmute" option.
@@ -240,10 +240,14 @@
                     self.bug.default_bugtask, name='+subscribe')
                 subscription_widget = (
                     subscribe_view.widgets['subscription'])
-                # The Unmute option is actually treated the same way as
-                # the unsubscribe option.
-                self.assertEqual(
-                    "unmute bug mail from this bug",
+                update_term = subscription_widget.vocabulary.getTermByToken(
+                    'update-subscription')
+                self.assertEqual(
+                    "unmute bug mail from this bug and subscribe me to this "
+                    "bug, or",
+                    update_term.title)
+                self.assertEqual(
+                    "unmute bug mail from this bug.",
                     subscription_widget.vocabulary.getTerm(self.person).title)
 
     def test_muted_subs_have_unmute_and_restore_option(self):
@@ -270,8 +274,8 @@
                     update_term.title)
 
     def test_unmute_unmutes(self):
-        # Using the "Unmute bug mail" option when the user has a muted
-        # subscription will unmute.
+        # Using the "Unmute bug mail" option when the user has muted their
+        # email will unmute.
         with person_logged_in(self.person):
             self.bug.mute(self.person, self.person)
 
@@ -287,7 +291,38 @@
                     self.bug.default_bugtask, form=form_data,
                     name='+subscribe')
                 self.assertFalse(self.bug.isMuted(self.person))
-                self.assertFalse(self.bug.isSubscribed(self.person))
+        subscription = self.bug.getSubscriptionForPerson(self.person)
+        self.assertIs(
+            None, subscription,
+            "There should be no BugSubscription for this person.")
+
+    def test_unmute_and_subscribe(self):
+        # Using the "unmute bug mail from this bug and subscribe me to this
+        # bug" option when the user has muted their email will unmute and
+        # subscribe.
+        with FeatureFixture({self.feature_flag: ON}):
+            with person_logged_in(self.person):
+                self.bug.mute(self.person, self.person)
+                level = BugNotificationLevel.METADATA
+                form_data = {
+                    'field.subscription': 'update-subscription',
+                    'field.bug_notification_level': level.title,
+                    # Although this isn't used we must pass it for the
+                    # sake of form validation.
+                    'field.actions.continue': 'Continue',
+                    }
+                create_initialized_view(
+                    self.bug.default_bugtask, form=form_data,
+                    name='+subscribe')
+                self.assertFalse(self.bug.isMuted(self.person))
+        subscription = self.bug.getSubscriptionForPerson(self.person)
+        self.assertEqual(
+            BugNotificationLevel.METADATA,
+            subscription.bug_notification_level,
+            "Bug notification level of subscription should be METADATA, is "
+            "actually %s." % (subscription.bug_notification_level.title
+                              if subscription is not None
+                              else '[not subscribed!]'))
 
     def test_bug_notification_level_field_has_widget_class(self):
         # The bug_notification_level widget has a widget_class property

=== modified file 'lib/lp/bugs/javascript/bugtask_index_portlets.js'
--- lib/lp/bugs/javascript/bugtask_index_portlets.js	2011-05-26 06:20:57 +0000
+++ lib/lp/bugs/javascript/bugtask_index_portlets.js	2011-06-02 15:51:45 +0000
@@ -305,8 +305,8 @@
         Y.lp.app.errors.display_error(link, error_msg);
     };
     handler.clearProgressUI = hide_spinner;
-    return function (e) {
-        if (!Y.Lang.isUndefined(e)) {
+    return function (e, do_next) {
+        if (Y.Lang.isValue(e)) {
             e.halt();
         }
         var is_muted = parent_node.hasClass('muted-true');
@@ -353,6 +353,9 @@
                     set_subscription_link_parent_class(
                         subscription_link, is_subscribed, is_dupe_subscribed);
                     subscription.disable_spinner(label);
+                    if (Y.Lang.isValue(do_next)) {
+                        do_next(response);
+                    }
                 },
                 failure: handler.getFailureHandler()
             },
@@ -366,7 +369,7 @@
  * Toggle the mute state.
  */
 
-function toggle_mute() {
+function toggle_mute(do_next) {
     if (LP.links.me === undefined) {
         return;
     }
@@ -374,7 +377,7 @@
     if (Y.Lang.isNull(link)) {
         return;
     }
-    return _get_toggle_mute(link)();
+    return _get_toggle_mute(link)(null, do_next);
 }
 
 /*
@@ -391,9 +394,11 @@
     if (is_muted) {
         parent_node.replaceClass('muted-false', 'muted-true');
         link.set('innerHTML', "Unmute bug mail");
+        link.replaceClass('mute', 'unmute');
     } else {
         parent_node.replaceClass('muted-true', 'muted-false');
         link.set('innerHTML', "Mute bug mail");
+        link.replaceClass('unmute', 'mute');
     }
 }
 
@@ -788,13 +793,6 @@
                 if (namespace.use_advanced_subscriptions) {
                     update_mute_after_subscription_change();
                 }
-
-                // Only when the link is added to the page, indicate success.
-                Y.on('contentready', function() {
-                    var flash_node = Y.one('.' + subscriber.get('css_name'));
-                    var anim = Y.lazr.anim.green_flash({ node: flash_node });
-                    anim.run();
-                }, '.' + subscriber.get('css_name'));
             },
 
             failure: error_handler.getFailureHandler()
@@ -948,10 +946,10 @@
     var html = Y.Node.create('<div><a></a></div>');
     html.addClass(terms.css_name);
 
-    if (subscription.is_direct_subscription()) {
+    if (subscription.has_duplicate_subscriptions()) {
+        html.set('id', 'dupe-' + terms.css_name);
+    } else {
         html.set('id', 'direct-' + terms.css_name);
-    } else {
-        html.set('id', 'dupe-' + terms.css_name);
     }
 
     html.one('a')
@@ -1184,46 +1182,52 @@
         var subscription_url =
             lp_bug_entry.get('self_link') + '/+subscription/' +
             person_name;
-        config = {
-            on: {
-                success: function(lp_subscription) {
-                    subscription.enable_spinner('Updating subscription...');
-                    lp_subscription.set(
+        var update_subscription = function(lp_subscription) {
+            subscription.enable_spinner('Updating subscription...');
+            lp_subscription.set(
+                'bug_notification_level',
+                form_data['field.bug_notification_level'][0]);
+            save_config = {
+                on: {
+                    success: function(e) {
+                        subscription.disable_spinner(
+                            'Edit subscription');
+                        link_parent.addClass('subscribed-true');
+                        link_parent.removeClass('subscribed-false');
+                        var anim = Y.lazr.anim.green_flash({
+                            node: link_parent
+                            });
+                        anim.run();
+                    },
+                    failure: function(e) {
+                        subscription.disable_spinner(
+                            'Edit subscription');
+                        var anim = Y.lazr.anim.red_flash({
+                            node: link_parent
+                            });
+                        anim.run();
+                    }
+                }
+            };
+            lp_subscription.lp_save(save_config);
+        };
+        if (is_muted) {
+            toggle_mute(function(lp_subscription) {
+                if (Y.Lang.isValue(lp_subscription)) {
+                    update_subscription(lp_subscription);
+                } else {
+                    subscription.set(
                         'bug_notification_level',
-                        form_data['field.bug_notification_level'][0]);
-                    save_config = {
-                        on: {
-                            success: function(e) {
-                                subscription.disable_spinner(
-                                    'Edit subscription');
-                                link_parent.addClass('subscribed-true');
-                                link_parent.removeClass('subscribed-false');
-                                var anim = Y.lazr.anim.green_flash({
-                                    node: link_parent
-                                    });
-                                anim.run();
-                                if (is_muted) {
-                                    // We're going to assume that the user
-                                    // wants to unmute also, since they
-                                    // bothered to change their subscription.
-                                    toggle_mute();
-                                }
-                            },
-                            failure: function(e) {
-                                subscription.disable_spinner(
-                                    'Edit subscription');
-                                var anim = Y.lazr.anim.red_flash({
-                                    node: link_parent
-                                    });
-                                anim.run();
-                            }
-                        }
-                    };
-                    lp_subscription.lp_save(save_config);
+                        form_data['field.bug_notification_level']);
+                    subscribe_current_user(subscription);
                 }
-            }
-        };
-        lp_client.get(subscription_url, config);
+            });
+        } else {
+            lp_client.get(
+                subscription_url,
+                {on: {success: update_subscription}}
+            );
+        }
 
     } else if (link_parent.hasClass('subscribed-false') &&
                link_parent.hasClass('dup-subscribed-false') &&

=== modified file 'lib/lp/bugs/javascript/subscription.js'
--- lib/lp/bugs/javascript/subscription.js	2011-05-24 15:16:49 +0000
+++ lib/lp/bugs/javascript/subscription.js	2011-06-02 15:51:45 +0000
@@ -29,7 +29,7 @@
     NOT_PERSONALLY_SUBSCRIBED: (
         "You are not directly subscribed to this bug, " +
             "but you have other subscriptions."),
-    MUTED_SUBSCRIPTION: "You have muted all email from this bug."
+    MUTED_SUBSCRIPTION: "You have muted all your direct email from this bug."
 };
 namespace._reasons = reasons;
 
@@ -717,9 +717,6 @@
         // The user has a muted direct subscription.
         reason = reasons.MUTED_SUBSCRIPTION;
         increases.push(action_ids.unmute);
-        increases.push(action_ids.subscribe_all);
-        increases.push(action_ids.subscribe_metadata);
-        increases.push(action_ids.subscribe_closed);
     } else if (info.direct.personal.length > 0) {
         // The user has a direct personal subscription.
         if (info.direct.personal.length > 1) {
@@ -775,6 +772,7 @@
         reductions.push(action_ids.mute);
         reductions.push(action_ids.subscribe_only_metadata);
         reductions.push(action_ids.subscribe_only_closed);
+        increases.push(action_ids.subscribe_all);
     }
     return {reason: reason, reductions: reductions, increases: increases};
 }
@@ -879,7 +877,7 @@
         .append(
             make_action_link(
                 'mute all emails from this bug',
-                 'no', 'mute', {}));
+                 'mute', 'mute', {}));
 }
 namespace._mute_action = mute_action;
 
@@ -890,8 +888,8 @@
     return make_action(action_ids.unmute)
         .append(
             make_action_link(
-                'receive emails about this bug from other subscriptions',
-                 'yes', 'unmute', {}));
+                'unmute emails from this bug',
+                 'unmute', 'unmute', {}));
 }
 namespace._unmute_action = unmute_action;
 
@@ -1064,15 +1062,16 @@
                                     info.direct.count += 1;
                                     info.count += 1;
                                 }
-                                info.muted = (
-                                    sub.bug_notification_level ===
-                                    'Nothing');
                             } else {
                                 if (Y.Lang.isValue(old)) {
                                     info.direct.personal.pop();
                                     info.direct.count -= 1;
                                     info.count -= 1;
                                 }
+                            }
+                            if (method_name === 'mute') {
+                                info.muted = true;
+                            } else if (method_name === 'unmute') {
                                 info.muted = false;
                             }
                             reveal_direct_description_actions(

=== modified file 'lib/lp/bugs/javascript/tests/test_subscription.js'
--- lib/lp/bugs/javascript/tests/test_subscription.js	2011-04-25 13:33:31 +0000
+++ lib/lp/bugs/javascript/tests/test_subscription.js	2011-06-02 15:51:45 +0000
@@ -1020,7 +1020,7 @@
              'select-only-direct-subscription-lifecycle'],
             direct_info.reductions);
         Y.ArrayAssert.itemsAreEqual(
-            [],
+            ['select-direct-subscription-discussion'],
             direct_info.increases);
     },
 
@@ -1042,7 +1042,7 @@
              'select-only-direct-subscription-lifecycle'],
             direct_info.reductions);
         Y.ArrayAssert.itemsAreEqual(
-            [],
+            ['select-direct-subscription-discussion'],
             direct_info.increases);
     },
 
@@ -1061,10 +1061,7 @@
             [],
             direct_info.reductions);
         Y.ArrayAssert.itemsAreEqual(
-            ['unmute-direct-subscription',
-             'select-direct-subscription-discussion',
-             'select-direct-subscription-metadata',
-             'select-direct-subscription-lifecycle'],
+            ['unmute-direct-subscription'],
             direct_info.increases);
     },
 
@@ -1753,14 +1750,14 @@
         this.assert_action_matches_expectations(
             module._mute_action, module._action_ids.mute,
             'mute all emails from this bug',
-            'no', 'mute', {}, true, true);
+            'mute', 'mute', {}, true, true);
     },
 
     test_unmute_action: function() {
         this.assert_action_matches_expectations(
             module._unmute_action, module._action_ids.unmute,
-            'receive emails about this bug from other subscriptions',
-            'yes', 'unmute', {}, true, false);
+            'unmute emails from this bug',
+            'unmute', 'unmute', {}, true, false);
     },
 
     test_subscribe_all_action: function() {

=== modified file 'lib/lp/bugs/templates/bug-portlet-subscription.pt'
--- lib/lp/bugs/templates/bug-portlet-subscription.pt	2011-05-20 21:09:40 +0000
+++ lib/lp/bugs/templates/bug-portlet-subscription.pt	2011-06-02 15:51:45 +0000
@@ -14,8 +14,9 @@
     <div id="sub-unsub-spinner">Subscribing...</div>
     <div tal:condition="request/features/malone.advanced-structural-subscriptions.enabled"
         tal:content="structure context_menu/editsubscriptions/render" />
-    <tal:show-mute condition="
-        request/features/malone.advanced-subscriptions.enabled">
+    <tal:show-mute
+        define="enabled request/features/malone.advanced-subscriptions.enabled"
+        condition="python: view.user and enabled">
       <div tal:attributes="class view/current_user_mute_class"
            id="mute-link-container">
         <span tal:replace="structure context_menu/mute_subscription/render"

=== modified file 'lib/lp/registry/javascript/structural-subscription.js'
--- lib/lp/registry/javascript/structural-subscription.js	2011-05-18 18:50:39 +0000
+++ lib/lp/registry/javascript/structural-subscription.js	2011-06-02 15:51:45 +0000
@@ -19,8 +19,8 @@
     ADVANCED_FILTER = 'advanced-filter',
     MATCH_ALL = 'match-all',
     MATCH_ANY = 'match-any',
-    MUTE_ICON_CLASS = 'no',
-    UNMUTE_ICON_CLASS = 'yes'
+    MUTE_ICON_CLASS = 'mute',
+    UNMUTE_ICON_CLASS = 'unmute'
     ;
 
 var cancel_button_html =
@@ -328,9 +328,9 @@
     typeof document.createElement('span').style.textOverflow === 'string';
 var is_gecko = navigator.product === 'Gecko';
 // If we're running on a Gecko-based browser (like Firefox) and it doesn't
-// have text-overflow then use the ellipsis hack.
-var using_ellipsis_hack = is_gecko && !ellipsis_supported;
-
+// have text-overflow then use the ellipsis hack.  We put it on the namespace
+// so tests can manipulate it.
+namespace.using_ellipsis_hack = is_gecko && !ellipsis_supported;
 /**
  * Populate the overlay element with the contents of the add/edit form.
  */
@@ -378,7 +378,7 @@
     if (side_portlets) {
         Y.one('#subscription-overlay-title').scrollIntoView();
     }
-    if (using_ellipsis_hack) {
+    if (namespace.using_ellipsis_hack) {
         // Look away.
         var header_text = header.get('text');
         var i;

=== modified file 'lib/lp/registry/javascript/tests/test_structural_subscription.js'
--- lib/lp/registry/javascript/tests/test_structural_subscription.js	2011-05-18 18:50:39 +0000
+++ lib/lp/registry/javascript/tests/test_structural_subscription.js	2011-06-02 15:51:45 +0000
@@ -422,11 +422,14 @@
 
             this.content_node = create_test_node();
             Y.one('body').appendChild(this.content_node);
+            this.using_ellipsis_hack = module.using_ellipsis_hack;
+            module.using_ellipsis_hack = true;
         },
 
         tearDown: function() {
             remove_test_node();
             delete this.content_node;
+            module.using_ellipsis_hack = this.using_ellipsis_hack;
         },
 
         test_title_ellipsisification: function() {
@@ -1684,7 +1687,7 @@
             Assert.areEqual(mute_label_node.getStyle('display'), 'none');
             var mute_link = filter_node.one('a.mute-subscription');
             Assert.isNotNull(mute_link);
-            Assert.isTrue(mute_link.hasClass('no'));
+            Assert.isTrue(mute_link.hasClass('mute'));
         },
 
         test_muted_rendering: function() {
@@ -1700,7 +1703,7 @@
             Assert.areEqual(mute_label_node.getStyle('display'), 'inline');
             var mute_link = filter_node.one('a.mute-subscription');
             Assert.isNotNull(mute_link);
-            Assert.isTrue(mute_link.hasClass('yes'));
+            Assert.isTrue(mute_link.hasClass('unmute'));
         },
 
         test_not_muted_toggle_muted: function() {
@@ -1720,7 +1723,7 @@
             Assert.areEqual(
                 this.lp_client.received[0][1][1], 'mute');
             Assert.areEqual(mute_label_node.getStyle('display'), 'inline');
-            Assert.isTrue(mute_link.hasClass('yes'));
+            Assert.isTrue(mute_link.hasClass('unmute'));
         },
 
         test_muted_toggle_not_muted: function() {
@@ -1741,7 +1744,7 @@
             Assert.areEqual(
                 this.lp_client.received[0][1][1], 'unmute');
             Assert.areEqual(mute_label_node.getStyle('display'), 'none');
-            Assert.isTrue(mute_link.hasClass('no'));
+            Assert.isTrue(mute_link.hasClass('mute'));
         },
 
         test_mute_spinner: function () {
@@ -1756,9 +1759,9 @@
             this.lp_client.named_post.halt = true;
             mute_link.simulate('click');
             Assert.isTrue(mute_link.hasClass('spinner'));
-            Assert.isFalse(mute_link.hasClass('no'));
+            Assert.isFalse(mute_link.hasClass('mute'));
             this.lp_client.named_post.resume();
-            Assert.isTrue(mute_link.hasClass('yes'));
+            Assert.isTrue(mute_link.hasClass('unmute'));
             Assert.isFalse(mute_link.hasClass('spinner'));
         },
 
@@ -1775,9 +1778,9 @@
             this.lp_client.named_post.halt = true;
             mute_link.simulate('click');
             Assert.isTrue(mute_link.hasClass('spinner'));
-            Assert.isFalse(mute_link.hasClass('no'));
+            Assert.isFalse(mute_link.hasClass('mute'));
             this.lp_client.named_post.resume();
-            Assert.isTrue(mute_link.hasClass('no'));
+            Assert.isTrue(mute_link.hasClass('mute'));
             Assert.isFalse(mute_link.hasClass('spinner'));
         }