launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #16587
[Merge] lp:~cprov/launchpad/ic-ui-stab-two into lp:launchpad
Celso Providelo has proposed merging lp:~cprov/launchpad/ic-ui-stab-two into lp:launchpad.
Requested reviews:
William Grant (wgrant): code
For more details, see:
https://code.launchpad.net/~cprov/launchpad/ic-ui-stab-two/+merge/214158
Creating *scroller* links to navigate from review comments to their related inline-comments.
It uses the existing link_scroller() implementation to change the page focus to the review-diff area and uses the DIffNav() to update the diff and comments to the related contents.
Also incorporating previous changes (ic-ui-stab-one) removing diff-content handling from Updater() widget and delegating to DiffNav() even when inline-comments are not enabled.
--
https://code.launchpad.net/~cprov/launchpad/ic-ui-stab-two/+merge/214158
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.
=== modified file 'lib/lp/app/javascript/comment.js'
--- lib/lp/app/javascript/comment.js 2014-02-25 16:53:24 +0000
+++ lib/lp/app/javascript/comment.js 2014-04-04 05:33:32 +0000
@@ -291,7 +291,7 @@
}, {
ATTRS: {
lp_client: {
- valueFn: function() { return new Y.lp.client.Launchpad() }
+ valueFn: function() { return new Y.lp.client.Launchpad(); }
},
animate: { value: true }
}
@@ -459,7 +459,8 @@
namespace.Comment.prototype.reset_contents.apply(this);
},
/**
- * Insert the specified HTML into the page.
+ * Insert the specified HTML into the page and fires
+ * 'CodeReviewComment.appended' event.
*
* @method insert_comment_HTML
* @param message_html The HTML of the comment to insert.
@@ -469,6 +470,7 @@
var comment = Y.Node.create(message_html);
conversation.appendChild(comment);
this.reset_contents();
+ this.fire('CodeReviewComment.appended');
Y.lp.anim.green_flash({node: comment}).run();
},
=== modified file 'lib/lp/code/browser/branchmergeproposal.py'
--- lib/lp/code/browser/branchmergeproposal.py 2014-02-25 19:40:56 +0000
+++ lib/lp/code/browser/branchmergeproposal.py 2014-04-04 05:33:32 +0000
@@ -61,7 +61,6 @@
SimpleTerm,
SimpleVocabulary,
)
-from zope.security.proxy import removeSecurityProxy
from lp import _
from lp.app.browser.launchpadform import (
@@ -112,7 +111,10 @@
)
from lp.services.librarian.interfaces.client import LibrarianServerError
from lp.services.messages.interfaces.message import IMessageSet
-from lp.services.propertycache import cachedproperty
+from lp.services.propertycache import (
+ cachedproperty,
+ get_property_cache,
+ )
from lp.services.webapp import (
canonical_url,
ContextMenu,
@@ -121,7 +123,6 @@
Link,
Navigation,
stepthrough,
- stepto,
)
from lp.services.webapp.authorization import check_permission
from lp.services.webapp.breadcrumb import Breadcrumb
@@ -684,8 +685,22 @@
for comment in merge_proposal.all_comments)
merge_proposal = merge_proposal.supersedes
comments = sorted(comments, key=operator.attrgetter('date'))
+ self._populate_previewdiffs(comments)
return CodeReviewConversation(comments)
+ def _populate_previewdiffs(self, comments):
+ """Lookup and populate caches for 'previewdiff_id'.
+
+ Only operated on objects providing `ICodeReviewComment`.
+ """
+ comments = [comment for comment in comments
+ if ICodeReviewComment.providedBy(comment)]
+ cric_set = getUtility(ICodeReviewInlineCommentSet)
+ relations = cric_set.getPreviewDiffsForComments(comments)
+ for comment in comments:
+ get_property_cache(
+ comment).previewdiff_id = relations.get(comment.id)
+
@property
def comments(self):
"""Return comments associated with this proposal, plus styling info.
=== modified file 'lib/lp/code/browser/codereviewcomment.py'
--- lib/lp/code/browser/codereviewcomment.py 2014-02-25 16:53:24 +0000
+++ lib/lp/code/browser/codereviewcomment.py 2014-04-04 05:33:32 +0000
@@ -98,6 +98,14 @@
return ''
@cachedproperty
+ def previewdiff_id(self):
+ inline_comment = getUtility(
+ ICodeReviewInlineCommentSet).getByReviewComment(self.comment)
+ if inline_comment is not None:
+ return inline_comment.previewdiff_id
+ return None
+
+ @cachedproperty
def body_text(self):
"""Get the body text for the message."""
return self.comment.message_body
@@ -290,8 +298,9 @@
data.get('publish_inline_comments')):
previewdiff_id = self.previewdiff.id
inline_comments = (
- self.branch_merge_proposal.getDraftInlineComments(diff_id))
- comment = self.branch_merge_proposal.createComment(
+ self.branch_merge_proposal.getDraftInlineComments(
+ previewdiff_id))
+ self.branch_merge_proposal.createComment(
self.user, subject=None, content=data['comment'],
parent=self.reply_to, vote=vote, review_type=review_type,
previewdiff_id=previewdiff_id, inline_comments=inline_comments)
=== modified file 'lib/lp/code/browser/tests/test_codereviewcomment.py'
--- lib/lp/code/browser/tests/test_codereviewcomment.py 2012-12-26 01:32:19 +0000
+++ lib/lp/code/browser/tests/test_codereviewcomment.py 2014-04-04 05:33:32 +0000
@@ -9,21 +9,33 @@
HTMLContains,
Tag,
)
-from testtools.matchers import Not
+from testtools.matchers import (
+ Equals,
+ Not,
+ )
+from zope.component import getUtility
from lp.code.browser.codereviewcomment import (
CodeReviewDisplayComment,
ICodeReviewDisplayComment,
)
+from lp.code.interfaces.codereviewinlinecomment import (
+ ICodeReviewInlineCommentSet,
+ )
from lp.services.webapp import canonical_url
from lp.services.webapp.interfaces import IPrimaryContext
from lp.testing import (
BrowserTestCase,
person_logged_in,
+ StormStatementRecorder,
TestCaseWithFactory,
verifyObject,
)
-from lp.testing.layers import DatabaseFunctionalLayer
+from lp.testing.layers import (
+ DatabaseFunctionalLayer,
+ LaunchpadFunctionalLayer,
+ )
+from lp.testing.matchers import HasQueryCount
class TestCodeReviewComments(TestCaseWithFactory):
@@ -54,6 +66,65 @@
verifyObject(ICodeReviewDisplayComment, display_comment)
+class TestCodeReviewCommentInlineComments(TestCaseWithFactory):
+ """Test `CodeReviewDisplayComment` integration with inline-comments."""
+
+ layer = LaunchpadFunctionalLayer
+
+ def makeInlineComment(self, person, comment, previewdiff=None,
+ comments=None):
+ # Test helper for creating inline comments.
+ if previewdiff is None:
+ previewdiff = self.factory.makePreviewDiff()
+ if comments is None:
+ comments = {'1': 'Foo'}
+ getUtility(ICodeReviewInlineCommentSet).ensureDraft(
+ previewdiff, person, comments)
+ cric = getUtility(ICodeReviewInlineCommentSet).publishDraft(
+ previewdiff, person, comment)
+ return cric
+
+ def test_display_comment_inline_comment(self):
+ # The CodeReviewDisplayComment links to related inline comments
+ # when they exist.
+ person = self.factory.makePerson()
+ with person_logged_in(person):
+ comment = self.factory.makeCodeReviewComment()
+ # `CodeReviewDisplayComment.previewdiff_id` is None if there
+ # is no related inline-comments.
+ display_comment = CodeReviewDisplayComment(comment)
+ self.assertIsNone(display_comment.previewdiff_id)
+ # Create a `PreviewDiff` and add inline-comments in
+ # the context of this review comment.
+ with person_logged_in(person):
+ previewdiff = self.factory.makePreviewDiff()
+ self.makeInlineComment(person, comment, previewdiff)
+ # 'previewdiff_id' property is cached, so its value did not
+ # change on the existing object.
+ self.assertIsNone(display_comment.previewdiff_id)
+ # On a new object, it successfully returns the `PreviewDiff.id`
+ # containing inline-comments related with this review comment.
+ display_comment = CodeReviewDisplayComment(comment)
+ self.assertEqual(previewdiff.id, display_comment.previewdiff_id)
+
+ def test_conversation_with_previewdiffs_populated(self):
+ # `CodeReviewConversation` comments have 'previewdiff_id'
+ # property pre-populated in view.
+ person = self.factory.makePerson()
+ merge_proposal = self.factory.makeBranchMergeProposal()
+ with person_logged_in(person):
+ for i in range(5):
+ comment = self.factory.makeCodeReviewComment(
+ merge_proposal=merge_proposal)
+ self.makeInlineComment(person, comment)
+ from lp.testing.views import create_initialized_view
+ view = create_initialized_view(merge_proposal, '+index')
+ conversation = view.conversation
+ with StormStatementRecorder() as recorder:
+ [c.previewdiff_id for c in conversation.comments]
+ self.assertThat(recorder, HasQueryCount(Equals(0)))
+
+
class TestCodeReviewCommentHtml(BrowserTestCase):
layer = DatabaseFunctionalLayer
=== modified file 'lib/lp/code/interfaces/codereviewinlinecomment.py'
--- lib/lp/code/interfaces/codereviewinlinecomment.py 2014-03-23 18:20:31 +0000
+++ lib/lp/code/interfaces/codereviewinlinecomment.py 2014-04-04 05:33:32 +0000
@@ -14,10 +14,7 @@
Attribute,
Interface,
)
-from zope.schema import (
- Datetime,
- TextLine,
- )
+from zope.schema import Datetime
from lp import _
from lp.code.interfaces.codereviewcomment import ICodeReviewComment
@@ -26,6 +23,8 @@
class ICodeReviewInlineComment(Interface):
+
+ previewdiff_id = Attribute(_('The preview diff ID'))
previewdiff = Reference(
title=_('The preview diff'), schema=IPreviewDiff, required=True,
readonly=True)
@@ -76,5 +75,17 @@
"""Return published comments for a given `CodeReviewComment`.
:param comment: The `CodeReviewComment` for linked to the inline
- comments.
+ comments.
+ """
+
+ def getPreviewDiffsForComments(comments):
+ """Return a dictionary container related comments and diffs.
+
+ Used for prepopulating `BranchMergeProposal` view caches.
+ `CodeReviewComment` and `PreviewDiff` are related by the existence
+ of `CodeReviewInlineComment`.
+
+ :param comments: a list of `CodeReviewComment`s
+ :return: a dictionary containing the given `CodeReviewComment.id`s
+ and the corresponding `PreviewDiff.id` or None.
"""
=== modified file 'lib/lp/code/javascript/branchmergeproposal.inlinecomments.js'
--- lib/lp/code/javascript/branchmergeproposal.inlinecomments.js 2014-02-28 01:19:39 +0000
+++ lib/lp/code/javascript/branchmergeproposal.inlinecomments.js 2014-04-04 05:33:32 +0000
@@ -35,7 +35,7 @@
header_row = namespace.create_row(
{'line_number': line_number});
}
- var content_row = header_row.next()
+ var content_row = header_row.next();
var widget = new Y.EditableText({
contentBox: content_row.one(
'#inlinecomment-' + line_number + '-draft'),
@@ -48,9 +48,9 @@
handle_widget_button = function(saved, comment) {
if (saved === false) {
handling_request = false;
- if (namespace.inlinecomments[line_number] === undefined) {
- header_row.remove(true);
- }
+ if (namespace.inlinecomments[line_number] === undefined) {
+ header_row.remove(true);
+ }
return;
}
@@ -119,7 +119,7 @@
'text', header_content);
// XXX cprov 20140226: the date should be formatted according to
// the user locale/timezone similar to fmt:displaydate.
- // We should leverage Y.Intl features.
+ // We should leverage Y.Intl features.
var fmt_date = 'on ' + Y.Date.format(
new Date(comment.date), {format: '%Y-%m-%d'});
headerspan.one('span').set('text', fmt_date);
@@ -129,7 +129,7 @@
headerrow.one('td').appendChild(headerspan);
// We want to have the comments in order after the line.
- var tr = Y.one('#diff-line-' + (parseInt(comment.line_number) + 1));
+ var tr = Y.one('#diff-line-' + (parseInt(comment.line_number, 10) + 1));
if (tr !== null) {
tr.insert(headerrow, 'before');
} else {
@@ -158,7 +158,7 @@
comments.forEach( function (comment) {
namespace.create_row(comment);
});
- },
+ }
},
parameters: {
previewdiff_id: namespace.current_previewdiff_id
@@ -170,7 +170,7 @@
var config_draft = {
on: {
success: function (drafts) {
- namespace.inlinecomments = {};
+ namespace.inlinecomments = {};
if (drafts === null) {
return;
}
@@ -179,11 +179,11 @@
Object.keys(drafts).forEach( function (line_number) {
var comment = {
'line_number': line_number,
- 'text': drafts[line_number],
+ 'text': drafts[line_number]
};
namespace.create_row(comment);
});
- },
+ }
},
parameters: {
previewdiff_id: namespace.current_previewdiff_id
@@ -227,6 +227,25 @@
lp_client: {
value: null
},
+
+ previewdiff_id: {
+ value: null
+ },
+
+ navigator: {
+ getter: function() {return this.get('srcNode').one('select');},
+ setter: function(navigator) {
+ var container = this.get('srcNode').one('.diff-navigator');
+ container.append(navigator);
+ var self = this;
+ navigator.on('change', function() {
+ self._showPreviewDiff(this.get('value'), false);
+ });
+ this._connectScrollers();
+ this._showPreviewDiff(navigator.get('value'), true);
+ }
+ }
+
}
});
@@ -234,7 +253,7 @@
Y.extend(DiffNav, Y.Widget, {
- /*
+ /**
* The initializer method that is called from the base Plugin class.
*
* @method initializer
@@ -249,47 +268,143 @@
}
},
- _connectNavigator: function(navigator) {
- var self = this;
+ /**
+ * Add the spinner image to the diff section title.
+ *
+ * @method set_status_updating
+ */
+ set_status_updating: function() {
+ var image = Y.Node.create('<img />')
+ .set('src', '/@@/spinner')
+ .set('title', 'Updating diff ...');
+ this.get('srcNode').one('h2').append(image);
+ },
+
+ /**
+ * Run finishing tasks after the diff content is updated.
+ *
+ * @method updated
+ */
+ set_status_updated: function() {
var rc = Y.lp.code.branchmergeproposal.reviewcomment;
(new rc.NumberToggle()).render();
- namespace.setup_inline_comments(navigator.get('value'));
-
- navigator.on('change', function() {
- var previewdiff_id = this.get('value');
- var preview_diff_uri = (
- LP.cache.context.web_link +
- '/+preview-diff/' + previewdiff_id + '/+diff');
- var container = self.get('srcNode').one('.diff-content');
- var config = {
- on: {
- success: function (diff_html) {
- container.set('innerHTML', diff_html);
- (new rc.NumberToggle()).render();
- namespace.setup_inline_comments(previewdiff_id);
- },
- failure: function(ignore, response, args) {
- Y.log('DiffNav: ' + preview_diff_uri +
- ' - ' + response.statusText);
- var error_note = Y.Node.create('<p />')
- .addClass('exception')
- .addClass('lowlight')
- .set('text', 'Failed to fetch diff content.');
- container.empty();
- container.append(error_note);
- },
- },
- };
- self.get('lp_client').get(preview_diff_uri, config);
+ if (this.get('previewdiff_id')) {
+ namespace.setup_inline_comments(this.get('previewdiff_id'));
+ }
+ },
+
+ /**
+ * Remove the spinner image from the diff section title.
+ *
+ * @method cleanup_status
+ */
+ cleanup_status: function() {
+ this.get('srcNode').all('h2 img').remove();
+ },
+
+ /**
+ * Update diff status on new review comments
+ *
+ * @method update_on_new_comment
+ */
+ update_on_new_comment: function() {
+ if (LP.cache.inline_diff_comments !== true) {
+ return;
+ }
+ namespace.populate_existing_comments();
+ this._connectScrollers();
+ },
+
+ /**
+ * Helper method to connect all inline-comment-scroller links to the
+ * to the diff navigator.
+ *
+ * @method _connectScrollers
+ */
+ _connectScrollers: function() {
+ var self = this;
+ var rc = Y.lp.code.branchmergeproposal.reviewcomment;
+ Y.all('.inline-comment-scroller').each( function(node) {
+ rc.link_scroller(node, '#review-diff', function() {
+ self._showPreviewDiff(
+ node.getAttribute('data-previewdiff-id'), false);
+ });
});
},
+ /**
+ * Helper method to update diff-content area according to given
+ * diff content uri
+ *
+ * @method _updateDiff
+ */
+ _updateDiff: function(preview_diff_uri) {
+ var self = this;
+ var container = this.get('srcNode').one('.diff-content');
+ var config = {
+ on: {
+ success: function (diff_html) {
+ container.set('innerHTML', diff_html);
+ self.set_status_updated();
+ },
+ failure: function(ignore, response, args) {
+ Y.log('DiffNav: ' + preview_diff_uri +
+ ' - ' + response.statusText);
+ var error_note = Y.Node.create('<p />')
+ .addClass('exception')
+ .addClass('lowlight')
+ .set('text', 'Failed to fetch diff content.');
+ container.empty();
+ container.append(error_note);
+ },
+ start: function() {
+ self.set_status_updating();
+ },
+ end: function() {
+ self.cleanup_status();
+ }
+ }
+ };
+ this.get('lp_client').get(preview_diff_uri, config);
+ },
+
+ /**
+ * Helper method to show the previewdiff for the given id.
+ * Do nothing if the current content is already displayed.
+ *
+ * @method _showPreviewDiff
+ */
+ _showPreviewDiff: function(previewdiff_id, force) {
+ var navigator = this.get('navigator');
+ if (!Y.Lang.isValue(navigator)) {
+ // DiffNav was not properly initialised.
+ return;
+ }
+ if (this.get('previewdiff_id') === previewdiff_id) {
+ // The requested diff is already presented.
+ return;
+ }
+ navigator.set('value', previewdiff_id);
+ this.set('previewdiff_id', previewdiff_id);
+ var preview_diff_uri = (
+ LP.cache.context.web_link +
+ '/+preview-diff/' + previewdiff_id + '/+diff');
+ this._updateDiff(preview_diff_uri);
+ },
+
+ /**
+ * Render diff navigator contents (navigator and diff area).
+ *
+ * @method renderUI
+ */
renderUI: function() {
+ var self = this;
if (LP.cache.inline_diff_comments !== true) {
- return
+ var preview_diff_uri = (LP.cache.context.web_link + '/++diff');
+ self._updateDiff(preview_diff_uri);
+ return;
}
- var self = this;
- var container = self.get('srcNode').one('.diff-navigator');
+ var container = this.get('srcNode').one('.diff-navigator');
container.empty();
var preview_diffs_uri = LP.cache.context.preview_diffs_collection_link;
var config = {
@@ -301,7 +416,7 @@
// XXX cprov 20140226: the date should be formatted
// according to the user locale/timezone similar to
// fmt:displaydate. We should leverage Y.Intl
- // features.
+ // features.
var fmt_date = 'on ' + Y.Date.format(
new Date(pd.get('date_created')),
{format: '%Y-%m-%d'});
@@ -309,29 +424,33 @@
var option = Y.Node.create('<option />')
.set('value', pd.get('id'))
.set('text', text);
- if (LP.cache.context.preview_diff_link ==
+ if (LP.cache.context.preview_diff_link ===
pd.get('self_link')) {
option.set('selected', 'selected');
}
navigator.append(option);
});
- container.append(navigator)
- self._connectNavigator(navigator);
+ self.set('navigator', navigator);
},
failure: function(ignore, response, args) {
Y.log('DiffNav: ' + preview_diffs_uri +
- ' - ' + response.statusText)
+ ' - ' + response.statusText);
var error_note = Y.Node.create('<p />')
.addClass('exception')
.addClass('lowlight')
.set('text', 'Failed to fetch available diffs.');
- container.empty();
container.append(error_note);
},
+ start: function() {
+ self.set_status_updating();
+ },
+ end: function() {
+ self.cleanup_status();
+ }
}
};
this.get('lp_client').get(preview_diffs_uri, config);
- },
+ }
});
=== modified file 'lib/lp/code/javascript/branchmergeproposal.reviewcomment.js'
--- lib/lp/code/javascript/branchmergeproposal.reviewcomment.js 2014-01-14 20:11:37 +0000
+++ lib/lp/code/javascript/branchmergeproposal.reviewcomment.js 2014-04-04 05:33:32 +0000
@@ -19,6 +19,9 @@
duration: 1,
easing: Y.Easing.easeOut
});
+// XXX cprov 20140402: only exposed so tests can fire its 'end' event
+// for testing hooked actions.
+namespace.window_scroll_anim = window_scroll_anim;
/*
* Connect all the links to their given actions.
=== modified file 'lib/lp/code/javascript/branchmergeproposal.updater.js'
--- lib/lp/code/javascript/branchmergeproposal.updater.js 2014-02-27 19:26:31 +0000
+++ lib/lp/code/javascript/branchmergeproposal.updater.js 2014-04-04 05:33:32 +0000
@@ -77,28 +77,6 @@
'summary_node').one('#summary-row-b-diff').one('td');
container.set('innerHTML', value);
}
- },
-
- /**
- * The HTML code for the diff.
- *
- * @attribute diff
- */
- diff: {
- getter: function() {
- if (this.get('pending')) {
- return '';
- }
- else {
- return this.get(
- 'srcNode').one('.diff-content').get('innerHTML');
- }
- },
- setter: function(value) {
- this._setup_diff_container();
- this.get(
- 'srcNode').one('.diff-content').set('innerHTML', value);
- }
}
}
@@ -214,7 +192,7 @@
.append(Y.Node.create('<h2 />')
.set("text", "Preview Diff "))
.append(Y.Node.create('<div />')
- .addClass("diff-content"))
+ .addClass("diff-navigator"))
.append(Y.Node.create('<div />')
.addClass("diff-content"));
this.get('srcNode').append(review_diff);
@@ -222,14 +200,12 @@
},
/*
- * Update the page with the last version of the diff and update the
- * stats.
+ * Update the page diff stats.
*
* @method update
*/
update: function() {
this.update_stats();
- this.update_diff();
},
/*
@@ -248,35 +224,10 @@
'#proposal-summary a.diff-link', '#review-diff');
var node = self.get('summary_node');
Y.lp.anim.green_flash({node: node}).run();
- },
- failure: function() {
- var node = self.get('summary_node');
- Y.lp.anim.red_flash({node: node}).run();
- }
- }
- };
- var mp_uri = LP.cache.context.web_link;
- this.get('lp_client').get(mp_uri + "/++diff-stats", config);
- },
-
-
- /*
- * Update the diff content with the last version.
- *
- * @method update_diff
- */
- update_diff: function() {
- var self = this;
- var config = {
- on: {
- success: function(diff) {
- self.set('diff', diff);
- var node = self.get('srcNode').one('.diff-content');
- Y.lp.anim.green_flash({node: node}).run();
self.fire(self.NAME + '.updated');
},
failure: function() {
- var node = self.get('srcNode').one('.diff-content');
+ var node = self.get('summary_node');
Y.lp.anim.red_flash({node: node}).run();
},
start: function() {
@@ -288,7 +239,7 @@
}
};
var mp_uri = LP.cache.context.web_link;
- this.get('lp_client').get(mp_uri + "/++diff", config);
+ this.get('lp_client').get(mp_uri + "/++diff-stats", config);
}
});
=== modified file 'lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.html'
--- lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.html 2014-02-27 19:26:31 +0000
+++ lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.html 2014-04-04 05:33:32 +0000
@@ -72,6 +72,12 @@
<li>lp.code.branchmergeproposal.inlinecomments.test</li>
</ul>
+ <a id="scroll-one" class="inline-comment-scroller" href=""
+ data-previewdiff-id="101">Go to One</a>
+
+ <a id="scroll-two" class="inline-comment-scroller" href=""
+ data-previewdiff-id="202">Go to Two</a>
+
<div id="review-diff">
<h2>Preview Diff</h2>
=== modified file 'lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js'
--- lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js 2014-02-28 03:32:53 +0000
+++ lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js 2014-04-04 05:33:32 +0000
@@ -8,20 +8,16 @@
tests.suite = new Y.Test.Suite('branchmergeproposal.inlinecomments Tests');
tests.suite.add(new Y.Test.Case({
- name: 'code.branchmergeproposal.inlinecomments_tests',
+ name: 'code.branchmergeproposal.inlinecomments_comments_tests',
setUp: function () {
// Loads testing values into LP.cache.
LP.cache.context = {
- web_link: "https://launchpad.dev/~foo/bar/foobr/+merge/1",
- self_link: "https://code.launchpad.dev/api/devel/~foo/bar/foobr/+merge/1",
- preview_diff_link: "https://code.launchpad.dev/api/devel/~foo/bar/foobr/+merge/1/preview_diff",
- preview_diffs_collection_link: "https://code.launchpad.dev/api/devel/~foo/bar/foobr/+merge/1/preview_diffs"
+ self_link: ("https://code.launchpad.dev/api/devel/" +
+ "~foo/bar/foobr/+merge/1")
};
LP.cache.inline_diff_comments = true;
- module.current_previewdiff_id = 1;
- module.inlinecomments = {};
},
tearDown: function () {},
@@ -47,6 +43,7 @@
{io_provider: mockio});
// Populate the page.
+ module.current_previewdiff_id = 1;
module.populate_existing_comments();
// LP was hit twice for fetching published and draft inline
@@ -74,7 +71,7 @@
{'line_number': '2',
'person': person_obj,
'text': 'This is preloaded.',
- 'date': '2012-08-12T10:00:00.00001+00:00'},
+ 'date': '2012-08-12T10:00:00.00001+00:00'}
];
mockio.success({
responseText: Y.JSON.stringify(published_comments),
@@ -92,9 +89,9 @@
Y.Assert.areEqual('This is preloaded.', text.get('text'));
// Draft comment is displayed.
- var header = Y.one('#diff-line-3').next();
+ header = Y.one('#diff-line-3').next();
Y.Assert.areEqual('Draft comment.', header.get('text'));
- var text = header.next();
+ text = header.next();
Y.Assert.areEqual('Zoing!', text.get('text'));
},
@@ -126,7 +123,7 @@
// Cancelling a draft comment attempt ...
line.simulate('dblclick');
- var ic_area = line.next().next();
+ ic_area = line.next().next();
ic_area.one('.yui3-ieditor-input>textarea').set('value', 'No!');
ic_area.one('.lazr-neg').simulate('click');
@@ -137,7 +134,7 @@
// Removing a draft comment by submitting an emtpy text.
line.simulate('dblclick');
- var ic_area = line.next().next();
+ ic_area = line.next().next();
ic_area.one('.yui3-ieditor-input>textarea').set('value', '');
ic_area.one('.lazr-pos').simulate('click');
@@ -154,10 +151,10 @@
called = true;
};
module.add_doubleclick_handler = add_doubleclick_handler;
- module.current_previewdiff_id = null
+ module.current_previewdiff_id = null;
LP.cache.inline_diff_comments = false;
- module.current_previewdiff_id = null
+ module.current_previewdiff_id = null;
module.setup_inline_comments(1);
Y.Assert.isFalse(called);
@@ -170,56 +167,53 @@
called = true;
};
module.add_doubleclick_handler = add_doubleclick_handler;
- module.current_previewdiff_id = null
+ module.current_previewdiff_id = null;
module.setup_inline_comments(1);
Y.Assert.isTrue(called);
Y.Assert.areEqual(1, module.current_previewdiff_id);
- },
-
- test_diff_nav_feature_flag_disabled: function() {
- // Disable feature flag.
- LP.cache.inline_diff_comments = false;
- // Overrides module LP client by one using 'mockio'.
- var mockio = new Y.lp.testing.mockio.MockIo();
- lp_client = new Y.lp.client.Launchpad({io_provider: mockio});
- // Create a fake setup_inline_comments for testing purposes.
- var called_diff_id = null;
- fake_setup = function(diff_id) {
- called_diff_id = diff_id;
- };
- module.setup_inline_comments = fake_setup;
- // Render DiffNav widget..
- (new module.DiffNav(
- {srcNode: Y.one('#review-diff'), lp_client: lp_client}
- )).render();
- // Nothing actually happens.
- Y.Assert.areEqual(0, mockio.requests.length);
- Y.Assert.isNull(called_diff_id);
- },
-
- test_diff_nav: function() {
- // Overrides module LP client by one using 'mockio'.
- var mockio = new Y.lp.testing.mockio.MockIo();
+ }
+
+ }));
+
+ tests.suite.add(new Y.Test.Case({
+ name: 'code.branchmergeproposal.inlinecomments_diffnav_tests',
+
+ setUp: function () {
+ // Loads testing values into LP.cache.
+ LP.cache.context = {
+ web_link: "https://launchpad.dev/~foo/bar/foobr/+merge/1",
+ self_link: ("https://code.launchpad.dev/api/devel/" +
+ "~foo/bar/foobr/+merge/1"),
+ preview_diff_link: ("https://code.launchpad.dev/api/devel/" +
+ "~foo/bar/foobr/+merge/1/preview_diff"),
+ preview_diffs_collection_link: (
+ "https://code.launchpad.dev/api/devel/" +
+ "~foo/bar/foobr/+merge/1/preview_diffs")
+ };
+
+ LP.cache.inline_diff_comments = true;
+ // Disable/Instrument inlinecomments hook.
+ var self = this;
+ self.inline_comments_requested_id = null;
+ module.setup_inline_comments = function(previewdiff_id) {
+ self.inline_comments_requested_id = previewdiff_id;
+ };
+ // Create an instrument DiffNav instance.
lp_client = new Y.lp.client.Launchpad(
- {io_provider: mockio});
- // Create a fake setup_inline_comments for testing purposes.
- var called_diff_id = null;
- fake_setup = function(diff_id) {
- called_diff_id = diff_id;
- };
- module.setup_inline_comments = fake_setup;
- // Render DiffNav widget on the test HTML content.
- (new module.DiffNav(
+ {io_provider: new Y.lp.testing.mockio.MockIo()});
+ this.diffnav = new module.DiffNav(
{srcNode: Y.one('#review-diff'), lp_client: lp_client}
- )).render();
- // diff-navigator section content is rendered based on the
- // preview_diffs API object.
- Y.Assert.areEqual(1, mockio.requests.length);
- Y.Assert.areSame(
- "/api/devel/~foo/bar/foobr/+merge/1/preview_diffs",
- mockio.last_request.url);
+ );
+
+ },
+
+ tearDown: function () {},
+
+ reply_previewdiffs: function() {
+ // test helper to reply 'available_diffs' collection via mockio.
+ var mockio = this.diffnav.get('lp_client').io_provider;
var preview_diffs = {
total_size: 2,
start: 0,
@@ -231,13 +225,70 @@
date_created: '2014-02-20T18:07:38.678947+00:00',
self_link: LP.cache.context.preview_diff_link}
]
- }
+ };
mockio.success({
responseText: Y.JSON.stringify(preview_diffs),
responseHeaders: {'Content-Type': 'application/json'}});
+ },
+
+ reply_diffcontent: function() {
+ // test helper to reply 'diff' content via mockio.
+ // it reuses the existing test template contents, but
+ // empties the page before replying it.
+ Y.one('.diff-content div div ul.horizontal').empty();
+ var diff_content = Y.one('.diff-content').get('innerHTML');
+ var mockio = this.diffnav.get('lp_client').io_provider;
+ Y.one('.diff-content').empty();
+ mockio.success({
+ responseText: diff_content,
+ responseHeaders: {'Content-Type': 'text/html'}});
+ },
+
+ test_diff_nav_feature_flag_disabled: function() {
+ // When rendered with the corresponding feature-flag disabled,
+ // Diff Navigator only updates the diff content with the latest
+ // previewdiff and does not create the navigator (<select>) nor
+ // fetches the inline comments.
+ LP.cache.inline_diff_comments = false;
+ this.diffnav.render();
+ mockio = this.diffnav.get('lp_client').io_provider;
+ Y.Assert.areEqual(1, mockio.requests.length);
+ Y.Assert.areSame(
+ "/~foo/bar/foobr/+merge/1/++diff",
+ mockio.last_request.url);
+ this.reply_diffcontent();
+ Y.Assert.isNull(this.diffnav.get('previewdiff_id'));
+ },
+
+ test_diff_nav_rendering: function() {
+ // When rendered the Diff Navigator fetches the available diffs
+ // collection and builds the selector, fetches and displays
+ // the diff contents for the most recent previewdiff and also
+ // fetches and displays the related inline comments.
+ this.diffnav.render();
+ // diff-navigator section content is rendered based on the
+ // preview_diffs API object.
+ var mockio = this.diffnav.get('lp_client').io_provider;
+ Y.Assert.areEqual(1, mockio.requests.length);
+ Y.Assert.areSame(
+ "/api/devel/~foo/bar/foobr/+merge/1/preview_diffs",
+ mockio.last_request.url);
+ this.reply_previewdiffs();
+ // The selected preview_diff content is retrieved.
+ Y.Assert.areEqual(2, mockio.requests.length);
+ Y.Assert.areSame(
+ "/~foo/bar/foobr/+merge/1/+preview-diff/101/+diff",
+ mockio.last_request.url);
+ this.reply_diffcontent();
// The local (fake) setup_inline_comments function
// was called with the selected diff_id value.
- Y.Assert.areEqual(101, called_diff_id);
+ Y.Assert.areEqual(101, this.inline_comments_requested_id);
+ // NumberToggle widget is rendered
+ Y.Assert.isNotNull(Y.one('.diff-content').one('#show-no'));
+ // Diff content is rendered/updated.
+ Y.Assert.areSame(
+ "foo bar",
+ Y.one('.diff-content table tbody tr td').next().get('text'));
// The option corresponding to the current 'preview_diff'
// is selected and contains the expected text (title and
// formatted date_created).
@@ -248,46 +299,107 @@
//Y.Assert.areEqual(
// 'r1 into r1 on 2014-02-20',
// Y.one('select').get('options').item(1).get('text'));
- // Simulate a change in the diff navigator.
+ },
+
+ test_diff_nav_changes: function() {
+ // Changes on the DiffNav selector result in diff content
+ // and inline comments updates.
+ this.diffnav.render();
+ this.reply_previewdiffs();
+ this.reply_diffcontent();
+ var mockio = this.diffnav.get('lp_client').io_provider;
+ Y.Assert.areEqual(2, mockio.requests.length);
+
Y.one('select').set('value', 202);
Y.one('select').simulate('change');
- // diff content was updated with the selected diff_id content.
+ Y.Assert.areEqual(3, mockio.requests.length);
+ Y.Assert.areSame(
+ "/~foo/bar/foobr/+merge/1/+preview-diff/202/+diff",
+ mockio.last_request.url);
+ this.reply_diffcontent();
+ Y.Assert.areEqual(202, this.diffnav.get('previewdiff_id'));
+ Y.Assert.areEqual(202, this.inline_comments_requested_id);
+ },
+
+ test_diff_nav_scrollers: function() {
+ // The Diff Navigator review comment *scrollers* are connected
+ // upon widget rendering and when clicked trigger the diff
+ // content update.
+ this.diffnav.render();
+ this.reply_previewdiffs();
+ this.reply_diffcontent();
+ var mockio = this.diffnav.get('lp_client').io_provider;
Y.Assert.areEqual(2, mockio.requests.length);
+ // We need to re-instrument the scroller in other to
+ // instantly fire the 'end' event (which runs the code
+ // that matters to us).
+ scroller = Y.one('#scroll-two');
+ scroller.on('click', function() {
+ var rc = Y.lp.code.branchmergeproposal.reviewcomment;
+ rc.window_scroll_anim.fire('end');
+ });
+ // Click the scroller results in a diff update.
+ scroller.simulate('click');
+ Y.Assert.areEqual(3, mockio.requests.length);
Y.Assert.areSame(
"/~foo/bar/foobr/+merge/1/+preview-diff/202/+diff",
mockio.last_request.url);
- // remove NumberToggle content before reusing 'diff-content'
- // content, so we do not have it rendered twice.
- Y.one('.diff-content div div ul.horizontal').empty();
- mockio.success({
- responseText: Y.one('.diff-content').get('innerHTML'),
- responseHeaders: {'Content-Type': 'text/html'}});
- Y.Assert.areEqual(202, called_diff_id);
+ this.reply_diffcontent();
+ Y.Assert.areEqual(202, this.diffnav.get('previewdiff_id'));
+ Y.Assert.areEqual(202, this.inline_comments_requested_id);
+ // If the scroller target diff is already displayed, the diff
+ // content is not refreshed.
+ scroller.simulate('click');
+ Y.Assert.areEqual(3, mockio.requests.length);
+ },
+
+ test_update_on_new_comment: function() {
+ // When a new comment is added to the page, it triggers
+ // a Diff Navigator action to update the inline comments and
+ // hook new inline-comment scroller links.
+ this.diffnav.set('navigator', Y.one('select'));
+ // Let's create add a new scroller to the page.
+ var new_scroller = Y.Node.create(
+ '<a id="scroll-three" class="inline-comment-scroller" ' +
+ 'href="" data-previewdiff-id="202">Another scroller</a>');
+ Y.one('#scroll-two').insert(new_scroller, 'after');
+ // and instrument the inline-comment updated function.
+ var populated = false;
+ module.populate_existing_comments = function () {
+ populated = true;
+ };
+ // Once called, update_on_new_comment() integrates the
+ // just-added scroller and updates the inline comments.
+ this.diffnav.update_on_new_comment();
+ Y.Assert.isTrue(new_scroller.hasClass('js-action'));
+ Y.Assert.isTrue(populated);
+ // Instrument the new scroller, so it will instantly fire
+ // the diff navigator hook and register the requested diff.
+ new_scroller.on('click', function() {
+ var rc = Y.lp.code.branchmergeproposal.reviewcomment;
+ rc.window_scroll_anim.fire('end');
+ });
+ var called_pd_id = null;
+ var called_force = null;
+ this.diffnav._showPreviewDiff = function (pd_id, force) {
+ called_pd_id = pd_id;
+ called_force = force;
+ };
+ // the new scroller works, it has requested and diff update
+ // to the encoded data-previewdiff-id.
+ new_scroller.simulate('click');
+ Y.Assert.areEqual(202, called_pd_id);
+ Y.Assert.isFalse(called_force);
},
test_diff_nav_failed_diff_content: function() {
- var mockio = new Y.lp.testing.mockio.MockIo();
- lp_client = new Y.lp.client.Launchpad(
- {io_provider: mockio});
- module.setup_inline_comments = function(diff_id) {};
- (new module.DiffNav(
- {srcNode: Y.one('#review-diff'), lp_client: lp_client}
- )).render();
- var preview_diffs = {
- total_size: 1,
- start: 0,
- entries: [
- {title: 'boing', id: 1,
- date_created: '2014-02-22T10:00:00.00001+00:00',
- self_link: 'something-else'}
- ]
- }
- mockio.success({
- responseText: Y.JSON.stringify(preview_diffs),
- responseHeaders: {'Content-Type': 'application/json'}});
- // Simulate a change in the diff navigator that will fail
- // to fetch the diff contents.
+ // An error message is presented when the Diff Navigator
+ // fails to fetch the selected diff contents.
+ this.diffnav.render();
+ this.reply_previewdiffs();
+ Y.one('select').set('value', 2);
Y.one('select').simulate('change');
+ var mockio = this.diffnav.get('lp_client').io_provider;
mockio.failure();
Y.Assert.areEqual(
'Failed to fetch diff content.',
@@ -295,17 +407,27 @@
},
test_diff_nav_failed_available_diffs: function() {
- var mockio = new Y.lp.testing.mockio.MockIo();
- lp_client = new Y.lp.client.Launchpad(
- {io_provider: mockio});
- // Simulate a failure when fetching available diffs.
- (new module.DiffNav(
- {srcNode: Y.one('#review-diff'), lp_client: lp_client}
- )).render();
+ // An error message is presented with the Diff Navigator
+ // fails to fetch the collection of available diffs.
+ this.diffnav.render();
+ var mockio = this.diffnav.get('lp_client').io_provider;
mockio.failure();
Y.Assert.areEqual(
'Failed to fetch available diffs.',
Y.one('.diff-navigator').get('text'));
+ },
+
+ test_status_indicators: function() {
+ // Indicating progress with the spinner image.
+ this.diffnav.set_status_updating();
+ Y.Assert.areEqual(
+ '/@@/spinner',
+ Y.one('h2').one('img').getAttribute('src'));
+ // Remove the spinner when the work is done.
+ this.diffnav.cleanup_status();
+ Y.Assert.areEqual(
+ 'Preview Diff',
+ Y.one('h2').get('innerHTML'));
}
}));
@@ -313,6 +435,6 @@
}, '0.1', {
requires: ['node-event-simulate', 'test', 'lp.testing.helpers',
'console', 'lp.client', 'lp.testing.mockio', 'widget',
- 'lp.code.branchmergeproposal.inlinecomments',
+ 'lp.code.branchmergeproposal.inlinecomments', 'lp.anim',
'lp.code.branchmergeproposal.reviewcomment']
});
=== modified file 'lib/lp/code/javascript/tests/test_branchmergeproposal.updater.js'
--- lib/lp/code/javascript/tests/test_branchmergeproposal.updater.js 2012-10-26 10:00:20 +0000
+++ lib/lp/code/javascript/tests/test_branchmergeproposal.updater.js 2014-04-04 05:33:32 +0000
@@ -43,9 +43,7 @@
test_default_values: function() {
Y.Assert.isTrue(this.updater.get('pending'));
- Y.Assert.areEqual(
- '',
- this.updater.get('diff'));
+ Y.Assert.isNull(this.updater.get('diff_stats'));
},
test__setup_diff_container: function() {
@@ -104,38 +102,6 @@
Y.one('h2').get('innerHTML'));
},
- test_get_diff: function() {
- this.updater._setup_diff_container();
- Y.one('.diff-content').set(
- 'innerHTML', 'this is a <span>diff</span>');
- Y.Assert.areEqual(
- 'this is a <span>diff</span>',
- this.updater.get('diff'));
- },
-
- test_set_diff: function() {
- this.updater.set('diff', 'this is a <span>diff</span>');
- Y.Assert.areEqual(
- 'this is a <span>diff</span>',
- Y.one('.diff-content').get('innerHTML'));
- },
-
- test_update_diff_success: function() {
- var mockio = new Y.lp.testing.mockio.MockIo();
- this.updater.get('lp_client').io_provider = mockio;
- Y.Assert.areEqual(
- '',
- this.updater.get('diff'));
- this.updater.update_diff();
- mockio.success({
- responseText: 'New <span>diff</span>',
- responseHeaders: {'Content-Type': 'text/html'}});
-
- Y.Assert.areEqual(
- 'New <span>diff</span>',
- this.updater.get('diff'));
- },
-
test_update_stats_success: function() {
var mockio = new Y.lp.testing.mockio.MockIo();
this.updater.get('lp_client').io_provider = mockio;
@@ -150,61 +116,22 @@
this.updater.get('diff_stats'));
},
- test_update_diff_fires_event: function() {
+ test_update_fires_event: function() {
var fired = false;
var mockio = new Y.lp.testing.mockio.MockIo();
this.updater.get('lp_client').io_provider = mockio;
this.updater.on(this.updater.NAME + '.updated', function() {
fired = true;
});
- this.updater.update_diff();
+ this.updater.update();
mockio.success({
- responseText: 'New <span>diff</span>',
+ responseText: '13 lines (+4/-0) 1 file modified',
responseHeaders: {'Content-Type': 'text/html'}});
-
Y.Assert.isTrue(fired);
}
}));
-/*
- * Tests for when the updater is built on top of an existing diff.
- *
- */
-var current_mp = Y.one('#current-mp').getContent();
-
-tests.suite.add(new Y.Test.Case({
-
- name: 'branchmergeproposal-updater-refresh-tests',
-
- setUp: function() {
- Y.one("#placeholder")
- .empty()
- .append(Y.Node.create(current_mp));
- var diff_area = Y.one('#diff-area');
- this.updater = new UpdaterWidget({srcNode: diff_area});
- },
-
- tearDown: function() {
- this.updater.destroy();
- },
-
- test_default_values: function() {
- Y.Assert.isFalse(this.updater.get('pending'));
- Y.Assert.areEqual(
- 'Example diff',
- this.updater.get('diff'));
- },
-
- test_get_diff: function() {
- Y.one('.diff-content').set(
- 'innerHTML', 'this is a <span>diff</span>');
- Y.Assert.areEqual(
- 'this is a <span>diff</span>',
- this.updater.get('diff'));
- }
-
-}));
tests.suite.add(new Y.Test.Case({
=== modified file 'lib/lp/code/model/codereviewinlinecomment.py'
--- lib/lp/code/model/codereviewinlinecomment.py 2014-03-23 18:20:31 +0000
+++ lib/lp/code/model/codereviewinlinecomment.py 2014-04-04 05:33:32 +0000
@@ -10,6 +10,7 @@
'CodeReviewInlineCommentSet',
]
+from storm.expr import LeftJoin
from storm.locals import (
Int,
Reference,
@@ -128,4 +129,17 @@
return IStore(CodeReviewInlineComment).find(
CodeReviewInlineComment,
CodeReviewInlineComment.comment_id == comment.id).one()
-
+
+ def getPreviewDiffsForComments(self, comments):
+ """See `ICodeReviewInlineCommentSet`."""
+ origin = [
+ CodeReviewComment,
+ LeftJoin(CodeReviewInlineComment,
+ CodeReviewComment.id ==
+ CodeReviewInlineComment.comment_id),
+ ]
+ relations = IStore(CodeReviewInlineComment).using(*origin).find(
+ (CodeReviewComment.id,
+ CodeReviewInlineComment.previewdiff_id),
+ CodeReviewComment.id.is_in(c.id for c in comments))
+ return dict(relations)
=== modified file 'lib/lp/code/model/tests/test_codereviewinlinecomment.py'
--- lib/lp/code/model/tests/test_codereviewinlinecomment.py 2014-03-23 18:20:31 +0000
+++ lib/lp/code/model/tests/test_codereviewinlinecomment.py 2014-04-04 05:33:32 +0000
@@ -55,7 +55,7 @@
previewdiff, person, {'2': 'foobar'})
drafts = getUtility(ICodeReviewInlineCommentSet).getDraft(
previewdiff, person)
- self.assertEqual({'2':'foobar'}, drafts)
+ self.assertEqual({'2': 'foobar'}, drafts)
def test_ensure_deletes(self):
# ICodeReviewInlineCommentSet.ensureDraft() will delete a draft if
@@ -86,7 +86,7 @@
previewdiff, person, {'1': 'bar'})
drafts = getUtility(ICodeReviewInlineCommentSet).getDraft(
previewdiff, person)
- self.assertEqual({'1':'bar'}, drafts)
+ self.assertEqual({'1': 'bar'}, drafts)
def test_publishDraft(self):
# ICodeReviewInlineCommentSet.publishDraft() will publish draft
@@ -117,7 +117,7 @@
previewdiff, person = self.makeCodeReviewInlineCommentDraft()
drafts = getUtility(ICodeReviewInlineCommentSet).getDraft(
previewdiff, person)
- self.assertEqual({'2':'foobar'}, drafts)
+ self.assertEqual({'2': 'foobar'}, drafts)
def test_get_published_sorted(self):
# ICodeReviewInlineCommentSet.findByPreviewDiff() will return a sorted
@@ -149,7 +149,7 @@
previewdiff=previewdiff, person=person, comment=comment_one,
comments={'1': 'one'})
comment_two = self.factory.makeCodeReviewComment()
- inline_two =self.makeCodeReviewInlineComment(
+ inline_two = self.makeCodeReviewInlineComment(
previewdiff=previewdiff, person=person, comment=comment_two,
comments={'2': 'two'})
cric_set = getUtility(ICodeReviewInlineCommentSet)
@@ -164,3 +164,27 @@
# Lookups for comments with no inline comments return an empty list.
comment_empty = self.factory.makeCodeReviewComment()
self.assertIsNone(cric_set.getByReviewComment(comment_empty))
+
+ def test_get_previewdiff_for_comments(self):
+ # For facilitating view cache population, all `PreviewDiffs`
+ # related with a set of `CodeReviewComment` (by having inline
+ # comments), can be retrieved as a dictionary from a single query.
+ expected_relations = {}
+ comments = []
+ person = self.factory.makePerson()
+ for i in range(5):
+ comment = self.factory.makeCodeReviewComment()
+ comments.append(comment)
+ inline_comment = self.makeCodeReviewInlineComment(
+ person=person, comment=comment)
+ expected_relations[comment.id] = inline_comment.previewdiff_id
+ # `CodeReviewComment` without inline comments have no corresponding
+ # `Previewdiff`.
+ comment = self.factory.makeCodeReviewComment()
+ comments.append(comment)
+ expected_relations[comment.id] = None
+ # The constructed relations match the ones returned by
+ # getPreviewDiffsForComments().
+ cric_set = getUtility(ICodeReviewInlineCommentSet)
+ found_relations = cric_set.getPreviewDiffsForComments(comments)
+ self.assertEqual(expected_relations, found_relations)
=== modified file 'lib/lp/code/templates/branchmergeproposal-index.pt'
--- lib/lp/code/templates/branchmergeproposal-index.pt 2014-02-27 17:45:09 +0000
+++ lib/lp/code/templates/branchmergeproposal-index.pt 2014-04-04 05:33:32 +0000
@@ -207,37 +207,35 @@
Y.on('load', function() {
var logged_in = LP.links['me'] !== undefined;
var ic = Y.lp.code.branchmergeproposal.inlinecomments;
+ var diffnav = new ic.DiffNav({srcNode: Y.one('#review-diff')});
if (logged_in) {
var comment = new Y.lp.app.comment.CodeReviewComment();
comment.render();
- comment._add_comment_success = function () {
- if (LP.cache.inline_diff_comments === true) {
- // No need to re-setup diff-line click handlers because
- // the diff content did not change.
- ic.populate_existing_comments();
- }
- }
+ comment.on('CodeReviewComment.appended', function () {
+ diffnav.update_on_new_comment();
+ });
Y.lp.code.branchmergeproposal.status.connect_status(conf);
}
Y.lp.code.branchmergeproposal.reviewcomment.connect_links();
- (new ic.DiffNav({srcNode: Y.one('#review-diff')})).render();
+ diffnav.render();
if (Y.Lang.isValue(LP.cache.merge_proposal_event_key)) {
- var updater = new Y.lp.code.branchmergeproposal.updater.UpdaterWidget(
- {
+ var upt = Y.lp.code.branchmergeproposal.updater;
+ var cfg = {
srcNode: Y.one('#diff-area'),
summary_node: Y.one('#proposal-summary')
- });
+ };
+ var updater = new upt.UpdaterWidget(cfg);
Y.on(LP.cache.merge_proposal_event_key, function(data) {
- if (Y.lp.code.branchmergeproposal.updater.is_mp_diff_updated(data)) {
+ if (upt.is_mp_diff_updated(data)) {
updater.update();
}
});
updater.on(updater.NAME + '.updated', function() {
- (new ic.DiffNav({srcNode: Y.one('#review-diff')})).render();
+ diffnav.render();
});
}
- }, window);
+ }, window);
Y.on('domready', function() {
Y.lp.app.widgets.expander.createByCSS(
=== modified file 'lib/lp/code/templates/codereviewcomment-header.pt'
--- lib/lp/code/templates/codereviewcomment-header.pt 2011-12-22 09:05:46 +0000
+++ lib/lp/code/templates/codereviewcomment-header.pt 2014-04-04 05:33:32 +0000
@@ -26,6 +26,11 @@
tal:attributes="href context/branch_merge_proposal/fmt:url">a
previous version</a>
of this proposal</span>
+ <span style="float: right;" tal:condition="context/previewdiff_id">
+ <a class="inline-comment-scroller" href=""
+ tal:attributes="data-previewdiff-id context/previewdiff_id"
+ >View inline comments</a>
+ </span>
</td>
<td class="bug-comment-index">
Follow ups