Merge lp:~danilo/launchpad/subscribe-unsubscribe into lp:launchpad

Proposed by Данило Шеган
Status: Merged
Approved by: Данило Шеган
Approved revision: no longer in the source branch.
Merged at revision: 12953
Proposed branch: lp:~danilo/launchpad/subscribe-unsubscribe
Merge into: lp:launchpad
Diff against target: 65 lines (+13/-5)
1 file modified
lib/lp/bugs/javascript/bugtask_index_portlets.js (+13/-5)
To merge this branch: bzr merge lp:~danilo/launchpad/subscribe-unsubscribe
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+59511@code.launchpad.net

Commit message

[r=adeuring][bug=770293] Allow unsubscribing from the bug page even without page reload when you subscribed inline.

Description of the change

= Bug 770293 =

After one subscribes to a bug, his user link and unsubscription icon is added to the subscribers list. However, unsubscribing action doesn't work because user is tagged as the "dupe subscriber" on subscribing, which causes the unsubscribe action to call unsubscribeFromDupes which silently succeeds but doesn't do anything.

= Implementation details =

The actual fix for this is addition of "subscription.set('is_direct', true)" to subscribe_current_user().

Everything else is drive-by fixes:

 - lines ~486: hide_spinner emitted a "failed" event, and was also called from on_success handler which emitted a "success" event; this caused unsubscribe action to be called twice because two "click" handlers were set-up, which caused a lot of confusion during debugging - the fix is to split out hide_spinner from the failure handler
 - lines ~610: the check if there are no other entries works better if we do it before we remove one of the entries (there can be at most two person links: one for direct, another for duplicate subscription), especially in a debugger (which can block things like animations); so, instead of checking if there are no links anymore after removal, we check if there was exactly one link before removal
 - lines ~1054: typo fix
 - lines ~1357: when someone "subscribes someone else" to a bug, an entry for them is added to the subscribers list; if they are a team, and current user is a member of that team, they should be able to unsubscribe them. However, this code was using the attribute directly which doesn't exist, so when fixed to use get(), it started working.

= Tests =

There is no easy way to test this, and since I am still doing some refactoring of the code in bugtask_index_portlets.js, I don't want to introduce lousy tests that will soon break.

= Demo & QA =

With the lack of tests, QA is very important for this. I seriously hope that we'll have enough time to introduce proper tests for this or it's inevitably going to break again in similar ways.

== For the actual bug ==

Go to https://bugs.launchpad.dev/bugs/1
"Subscribe" yourself, "Unsubscribe" yourself (eg. using the "(-)" icon next to your name in the subscribers list), and reload to make sure that you have been unsubscribed.

== For drive-by fixes ==

1. Try subscribing the same team to a bug, and to a duplicate of the bug. From the 'primary' bug, unsubscribe a team from the duplicate, and from the bug using "(-)" icons
2. Observe that the unsubscribe (-) icon is added for these teams even without page reload

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/bugs/javascript/bugtask_index_portlets.js

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

(15:45:52) adeuring: danilos: nice work. Just one minor remark: for me, the variable name "person_links" sounds more like a sequence, but it contains the number of links. What about renaming it to num_person_links?
(15:45:56) adeuring: but anyway, r0me
(15:46:00) adeuring: r=me
(15:46:19) danilos: adeuring, heh, I know, but I'll have to wrap the line then :)
(15:46:24) danilos: adeuring, thanks, I'll fix it
(15:46:49) adeuring: danilos: I see your point ;) leave it if you think it looks nicer ;)

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/javascript/bugtask_index_portlets.js'
2--- lib/lp/bugs/javascript/bugtask_index_portlets.js 2011-04-29 00:58:32 +0000
3+++ lib/lp/bugs/javascript/bugtask_index_portlets.js 2011-04-29 14:02:37 +0000
4@@ -486,6 +486,10 @@
5 function hide_spinner() {
6 Y.one('#subscribers-portlet-dupe-spinner').setStyle(
7 'display', 'none');
8+ }
9+
10+ function on_failure(transactionid, response, args) {
11+ hide_spinner();
12 // Fire a custom event to signal failure, so that
13 // any remaining unsub icons can be hooked up.
14 namespace.portlet.fire('bugs:dupeportletloadfailed');
15@@ -507,7 +511,7 @@
16 }
17
18 var config = {on: {success: on_success,
19- failure: hide_spinner}};
20+ failure: on_failure}};
21 var url = Y.one(
22 '#subscribers-from-dupes-content-link').getAttribute(
23 'href').replace('bugs.', '');
24@@ -610,10 +614,11 @@
25 var config = {
26 on: {
27 success: function(client) {
28+ var num_person_links = Y.all(
29+ '.' + person.get('css_name')).size();
30 Y.lp.bugs.subscribers_list.remove_user_link(person, is_dupe);
31- var person_link = Y.one('.' + person.get('css_name'));
32 var has_direct, has_dupes;
33- if (Y.Lang.isNull(person_link) &&
34+ if (num_person_links === 1 &&
35 subscription.is_current_user_subscribing()) {
36 // Current user has been completely unsubscribed.
37 subscription.disable_spinner(
38@@ -719,6 +724,9 @@
39 var subscriber = subscription.get('subscriber');
40 var bug_notification_level = subscription.get('bug_notification_level');
41
42+ // This is always a direct subscription.
43+ subscription.set('is_direct', true);
44+
45 var error_handler = new Y.lp.client.ErrorHandler();
46 error_handler.clearProgressUI = function () {
47 subscription.disable_spinner();
48@@ -1054,7 +1062,7 @@
49 var not_unsubscribables = [];
50
51 // Use the list of subscribers pulled from the DOM to have sortable
52- // lists of unsubscribable vs. not unsubscribale person links.
53+ // lists of unsubscribable vs. not unsubscribable person links.
54 var all_subscribers = Y.all('#subscribers-links div');
55 if (all_subscribers.size() > 0) {
56 all_subscribers.each(function(sub_link) {
57@@ -1357,7 +1365,7 @@
58 var team_member = false;
59 var i;
60 for (i=0; i<result.entries.length; i++) {
61- if (result.entries[i].member_link ===
62+ if (result.entries[i].get('member_link') ===
63 Y.lp.client.get_absolute_uri(
64 subscription.get(
65 'subscriber').get('uri'))) {