Skip to content

Commit

Permalink
Merge branch 'release-3.0.x' into release-4.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
chipx86 committed Dec 4, 2020
2 parents f520388 + db9099c commit 5fa65ae
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 14 deletions.
23 changes: 16 additions & 7 deletions reviewboard/reviews/templatetags/reviewtags.py
Expand Up @@ -308,24 +308,33 @@ def reply_section(context, review, comment, context_type, context_id,
The context to use when rendering the template included by the
inclusion tag.
"""
user = context.get('user', None)
user = context.get('user')

if comment != '':
if type(comment) is ScreenshotComment:
context_id += 's'
elif type(comment) is FileAttachmentComment:
if context_type == 'body_top':
anchor_prefix = 'header-reply'
elif context_type == 'body_bottom':
anchor_prefix = 'footer-reply'
else:
assert comment
comment_cls = type(comment)

if comment_cls is FileAttachmentComment:
context_id += 'f'
elif type(comment) is GeneralComment:
elif comment_cls is GeneralComment:
context_id += 'g'
elif comment_cls is ScreenshotComment:
context_id += 's'

anchor_prefix = comment.anchor_prefix
context_id += six.text_type(comment.id)

return {
'reply_anchor_prefix': anchor_prefix,
'review': review,
'comment': comment,
'context_type': context_type,
'context_id': context_id,
'user': context.get('user'),
'user': user,
'local_site_name': context.get('local_site_name'),
'is_read_only': is_site_read_only_for(user),
'reply_to_is_empty': reply_to_text == '',
Expand Down
171 changes: 171 additions & 0 deletions reviewboard/reviews/tests/test_reviewtags.py
Expand Up @@ -442,6 +442,177 @@ def test_spanning_last_chunk(self):
self.assertEqual(result, 'Lines 30-60 (original), 61-79 (patched)')


class ReplySectionTests(TestCase):
"""Unit tests for the {% reply_section %} template tag."""

fixtures = ['test_users']

def test_with_body_top(self):
"""Testing {% reply_section %} with body_top"""
review_request = self.create_review_request(publish=True)
review = self.create_review(review_request, publish=True)
self.create_reply(review,
body_top_reply_to=review,
publish=True)

self._test_reply_section(context_type='body_top',
context_id='rcbt',
review=review,
expected_context_id='rcbt',
expected_reply_anchor_prefix='header-reply')

def test_with_body_bottom(self):
"""Testing {% reply_section %} with body_bottom"""
review_request = self.create_review_request(publish=True)
review = self.create_review(review_request, publish=True)
self.create_reply(review,
body_bottom_reply_to=review,
publish=True)

self._test_reply_section(context_type='body_bottom',
context_id='rcbb',
review=review,
expected_context_id='rcbb',
expected_reply_anchor_prefix='footer-reply')

@add_fixtures(['test_scmtools'])
def test_with_diff_comment(self):
"""Testing {% reply_section %} with diff comment"""
review_request = self.create_review_request(publish=True,
create_repository=True)
diffset = self.create_diffset(review_request)
filediff = self.create_filediff(diffset)

review = self.create_review(review_request, publish=True)
comment = self.create_diff_comment(review, filediff)

reply = self.create_reply(review, publish=True)
self.create_diff_comment(reply, filediff,
reply_to=comment)

self._test_reply_section(context_type='diff_comments',
context_id='rc',
review=review,
comment=comment,
expected_context_id='rc%s' % comment.pk,
expected_reply_anchor_prefix='comment')

def test_with_general_comment(self):
"""Testing {% reply_section %} with general comment"""
review_request = self.create_review_request(publish=True)

review = self.create_review(review_request, publish=True)
comment = self.create_general_comment(review)

reply = self.create_reply(review, publish=True)
self.create_general_comment(reply,
reply_to=comment)

self._test_reply_section(context_type='general_comments',
context_id='rc',
review=review,
comment=comment,
expected_context_id='rcg%s' % comment.pk,
expected_reply_anchor_prefix='gcomment')

def test_with_file_attachment_comment(self):
"""Testing {% reply_section %} with file attachment comment"""
review_request = self.create_review_request(publish=True)
file_attachment = self.create_file_attachment(review_request)

review = self.create_review(review_request, publish=True)
comment = self.create_file_attachment_comment(review, file_attachment)

reply = self.create_reply(review, publish=True)
self.create_file_attachment_comment(reply, file_attachment,
reply_to=comment)

self._test_reply_section(context_type='file_attachment_comments',
context_id='rc',
review=review,
comment=comment,
expected_context_id='rcf%s' % comment.pk,
expected_reply_anchor_prefix='fcomment')

def test_with_screenshot_comment(self):
"""Testing {% reply_section %} with screenshot comment"""
review_request = self.create_review_request(publish=True)
screenshot = self.create_screenshot(review_request)

review = self.create_review(review_request, publish=True)
comment = self.create_screenshot_comment(review, screenshot)

reply = self.create_reply(review, publish=True)
self.create_screenshot_comment(reply, screenshot,
reply_to=comment)

self._test_reply_section(context_type='screenshot_comments',
context_id='rc',
review=review,
comment=comment,
expected_context_id='rcs%s' % comment.pk,
expected_reply_anchor_prefix='scomment')

def _test_reply_section(self, context_type, context_id, review,
expected_context_id, expected_reply_anchor_prefix,
comment=None):
"""Render the template tag and check the output.
Args:
context_type (unicode):
The context type to pass to the template tag.
context_id (unicode):
The context ID to pass to the template tag.
review (reviewboard.reviews.models.review.Review):
The review being replied to.
expected_context_id (unicode):
The expected rendered context ID (found in the element ID).
expected_reply_anchor_prefix (unicode):
The expected reply anchor (found in the
``data-reply-anchor-prefix=`` attribute).
comment (reviewboard.reviews.models.base_comment.BaseComment,
optional):
The comment being replied to, if replying to a comment.
Raises:
AssertionError:
The rendered content didn't match the expected criteria.
"""
request = self.create_http_request()

t = Template(
r'{% load reviewtags %}'
r'{% reply_section review comment context_type context_id %}'
)
html = t.render(RequestContext(request, {
'review': review,
'comment': comment,
'context_type': context_type,
'context_id': context_id,
}))

s = [
'<div id="%s-%s"\\s+'
'class="comment-section"\\s+'
'data-context-type="%s"\\s+'
'data-reply-anchor-prefix="%s"\\s+'
% (expected_context_id, review.pk, context_type,
expected_reply_anchor_prefix)
]

if comment:
s.append('data-context-id="%s"' % comment.pk)

s.append('>')

self.assertRegexpMatches(html, ''.join(s))


class CommentRepliesTests(TestCase):
"""Unit tests for the comment_replies template tag."""

Expand Down
Expand Up @@ -6,6 +6,7 @@
*/
RB.ReviewRequestPage.ReviewReplyEditor = Backbone.Model.extend({
defaults: {
anchorPrefix: null,
contextID: null,
contextType: null,
commentID: null,
Expand Down
Expand Up @@ -8,6 +8,13 @@ RB.ReviewRequestPage.ReviewReplyEditorView = Backbone.View.extend({
commentTemplate: _.template(dedent`
<li <% if (isDraft) { %>class="draft"<% } %>
<% if (commentID) { %>data-comment-id="<%= commentID %>"<% } %>>
<% if (anchorName) { %>
<a class="comment-anchor" name="<%- anchorName %>"></a>
<div class="floating-anchor">
<a href="#<%- anchorName %>"
class="fa fa-link fa-flip-horizontal"></a>
</div>
<% } %>
<div class="comment-author">
<label for="<%= id %>">
<div class="avatar-container">
Expand Down Expand Up @@ -214,6 +221,7 @@ RB.ReviewRequestPage.ReviewReplyEditorView = Backbone.View.extend({
moment().utcOffset(userSession.get('timezoneOffset')));

const $el = $(this.commentTemplate(_.extend({
anchorName: null,
id: _.uniqueId('draft_comment_'),
text: '',
commentID: null,
Expand Down Expand Up @@ -277,10 +285,13 @@ RB.ReviewRequestPage.ReviewReplyEditorView = Backbone.View.extend({
*/
_onPublished() {
if (this._$draftComment) {
const model = this.model;

this._$draftComment.replaceWith(this._makeCommentElement({
commentID: this.model.get('commentID'),
text: this.model.get('text'),
richText: this.model.get('richText'),
anchorName: model.get('anchorPrefix') + model.get('anchorID'),
commentID: model.get('commentID'),
text: model.get('text'),
richText: model.get('richText'),
isDraft: false,
}));

Expand Down
Expand Up @@ -110,6 +110,7 @@ RB.ReviewRequestPage.ReviewView = Backbone.View.extend({
_.each(this.$('.comment-section'), el => {
const $el = $(el);
const editor = new RB.ReviewRequestPage.ReviewReplyEditor({
anchorPrefix: $el.data('reply-anchor-prefix'),
contextID: $el.data('context-id'),
contextType: $el.data('context-type'),
review: this.model,
Expand Down
Expand Up @@ -13,6 +13,8 @@ suite('rb/reviewRequestPage/views/ReviewReplyEditorView', function() {
(options, context) => options.success.call(context));

editor = new RB.ReviewRequestPage.ReviewReplyEditor({
anchorPrefix: 'header-reply',
anchorID: 10,
review: new RB.Review({
id: 42,
parentObject: new RB.ReviewRequest(),
Expand Down Expand Up @@ -109,6 +111,16 @@ suite('rb/reviewRequestPage/views/ReviewReplyEditorView', function() {
expect(view._$draftComment).toBe(null);
expect($.fn.user_infobox).toHaveBeenCalled();
expect($.fn.timesince).toHaveBeenCalled();

const $anchor = $el.children('.comment-anchor');
expect($anchor.length).toBe(1);
expect($anchor.attr('name')).toBe('header-reply10');

const $floatingAnchor = $el.find('> .floating-anchor > a');
expect($floatingAnchor.length).toBe(1);
expect($floatingAnchor.attr('href')).toBe('#header-reply10');
expect($floatingAnchor.hasClass('fa fa-link fa-flip-horizontal'))
.toBe(true);
});
});

Expand Down
@@ -1,4 +1,4 @@
suite('rb/views/ReviewView', function() {
suite('rb/reviewRequestPage/views/ReviewView', function() {
const template = _.template(dedent`
<div class="review review-request-page-entry">
<div class="review-request-page-entry-contents">
Expand All @@ -16,7 +16,9 @@ suite('rb/views/ReviewView', function() {
</div>
</div>
<div class="review-comment-thread">
<div class="comment-section" data-context-type="body_top">
<div class="comment-section"
data-context-type="body_top"
data-reply-anchor-prefix="header-reply">
<a class="add_comment_link"></a>
<ul class="reply-comments">
<li class="draft" data-comment-id="456">
Expand All @@ -29,7 +31,8 @@ suite('rb/views/ReviewView', function() {
<li>
<div class="review-comment-thread">
<div class="comment-section" data-context-id="123"
data-context-type="diff_comments">
data-context-type="diff_comments"
data-reply-anchor-prefix="comment">
<a class="add_comment_link"></a>
<ul class="reply-comments"></ul>
</div>
Expand All @@ -42,7 +45,9 @@ suite('rb/views/ReviewView', function() {
</div>
</div>
<div class="review-comment-thread">
<div class="comment-section" data-context-type="body_bottom">
<div class="comment-section"
data-context-type="body_bottom"
data-reply-anchor-prefix="footer-reply">
<a class="add_comment_link"></a>
<ul class="reply-comments"></ul>
</div>
Expand Down Expand Up @@ -159,16 +164,19 @@ suite('rb/views/ReviewView', function() {
it('Initial state populated', function() {
let model = view._replyEditorViews[0].model;

expect(model.get('anchorPrefix')).toBe('header-reply');
expect(model.get('contextID')).toBe(null);
expect(model.get('contextType')).toBe('body_top');
expect(model.get('hasDraft')).toBe(true);

model = view._replyEditorViews[1].model;
expect(model.get('anchorPrefix')).toBe('comment');
expect(model.get('contextID')).toBe(123);
expect(model.get('contextType')).toBe('diff_comments');
expect(model.get('hasDraft')).toBe(false);

model = view._replyEditorViews[2].model;
expect(model.get('anchorPrefix')).toBe('footer-reply');
expect(model.get('contextID')).toBe(null);
expect(model.get('contextType')).toBe('body_bottom');
expect(model.get('hasDraft')).toBe(false);
Expand Down
1 change: 1 addition & 0 deletions reviewboard/templates/reviews/review_reply_section.html
Expand Up @@ -2,6 +2,7 @@

<div id="{{context_id}}-{{review.pk}}" class="comment-section"
data-context-type="{{context_type}}"
data-reply-anchor-prefix="{{reply_anchor_prefix}}"
{% if comment %}data-context-id="{{comment.pk}}"{% endif %}>
<div class="issue-indicator"></div>
<ol class="reply-comments">
Expand Down

0 comments on commit 5fa65ae

Please sign in to comment.