• 
      

    Fix bugs related to general comments and Ship It indications in review emails.

    Review Request #8240 — Created June 12, 2016 and submitted

    Information

    Review Board
    release-3.0.x
    a36a3b6...

    Reviewers

    Address two inconsistencies where general comments were not being handled in
    the same fashion as the other classes of comments (e.g. diff, file attachment,
    and screenshot comments). These would lead to errant details in review emails
    for reviews where a Ship It had been declared.

    1. The existence of general comments was not being considered when determining
      the ship_it_only state of Review objects. This resulted in review emails
      where the X-ReviewBoard-ShipIt-Only header was set even when general comments
      were present.
    2. The existence of general comments with open issues was not being considered
      when determining the need for the "Fix it, then Ship it!" designation for review
      emails. This produced review emails with the "Ship it!" designation, even when
      the review contained general comments with issues.

    To resolve both bugs, separate queries that accounted for the other three
    classes of comments were centralized into a new function, has_comments(),
    and a query for general comments was introduced here as well. Furthermore, with
    respect to item 2, the logic for determining the presence of any comments with
    issues is now conditioned on review.ship_it, since this is the only state under
    which this information is necessary. Previously this was calculated
    unconditionally, which was overkill.

    To facilitate consistency and testability, a FIX_IT_THEN_SHIP_IT_TEXT
    constant has been added to the Review class to hold the
    "Fix it, then Ship it!" text. This is analogous to SHIP_IT_TEXT which
    already exists. These constants are now utilized in the review email templates
    rather than the prior string literals. This introduces one minor delta for
    Ship It emails. Previously, the string literal was "Ship it!", whereas the
    string in SHIP_IT_TEXT is "Ship It!'. That is, the "I" in "It" is now
    capitalized.

    Also, added GeneralComment to the list of comment classes discussed in the
    documentation for the CommentDetailDisplayHook.

    • Augmented all existing unit tests related to review emails with Ship It to
      verify that "Fix it, then Ship it!" does not appear in the message.
    • Added a new unit test for review emails with a Ship It and general
      comments. This is analogous to existing tests for the other three classes of
      comments. This test would fail without the fix.
    • Added new unit tests for all four classes of comments to further test review
      email's with a Ship It and comments with an opened issue. Prior to the fix,
      the specific test for the general comment class would fail.

    Confirmed all unit tests pass. Built docs and reviewed.

    Description From Last Updated

    Checking review.ship_it_only and then re-doing queries to check for open issues means we have to hit the database up to …

    brennie brennie

    Can we refactor this into a method like: def has_comments(check_for_issues=False): qs = [ self.comments, self.file_attachment_comments, self.screenshot_comments, self.general_comments, ] if check_for_issues: …

    brennie brennie

    Single space after a period. "Whether or not" "with open issues only"

    brennie brennie

    Mind adding a comment next to these that these are explicitly not marked for localization because they're used in e-mails, …

    david david

    I think this would be slightly clearer if the parameter was named only_issues

    david david

    This should be in the imperative mood ("Return whether" rather than "Returns whether")

    david david

    This can easily fit all on one line.

    david david

    The description should be on the line after the type: bool: ``True`` if the review contains any comments/issues and ``False`` …

    david david
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
    2. 
        
    brennie
    1. Thanks for catching this! I have some refactoring suggestions to clean up the code (it was already a bit messy before you got to it).

    2. reviewboard/notifications/email.py (Diff revision 1)
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      Checking review.ship_it_only and then re-doing queries to check for open issues means we have to hit the database up to 8 times (twice for each comment type).

      I also prefer the name has_issues over fix_it_then_ship_it (its more wordy). However, you are right that we do not always need to calculate it!

      With my suggested refactor for has_comments, we can do:

      has_issues = (review.ship_it and
                    review.has_comments(check_for_issues=True))
      

      This is a lot cleaner, IMO.

    3. reviewboard/reviews/models/review.py (Diff revision 1)
       
       
       
       
       
      Show all issues

      Can we refactor this into a method like:

      def has_comments(check_for_issues=False):
          qs = [
              self.comments,
              self.file_attachment_comments,
              self.screenshot_comments,
              self.general_comments,
          ]
      
          if check_for_issues:
              qs = [
                  q.filter(issue_opened=True)
                  for q in qs
              ]
      
          return any(
              q.exists()
              for q in qs
          )
      

      Then we can refactor ship_it_only to use has_comments(check_for_issues=False) and mail_review can be refactored as well.

    4. 
        
    gmyers
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
    2. 
        
    david
    1. 
        
    2. reviewboard/reviews/models/review.py (Diff revision 2)
       
       
       
      Show all issues

      Mind adding a comment next to these that these are explicitly not marked for localization because they're used in e-mails, where we don't want to take the submitting user's locale into effect?

    3. reviewboard/reviews/models/review.py (Diff revision 2)
       
       
      Show all issues

      I think this would be slightly clearer if the parameter was named only_issues

    4. reviewboard/reviews/models/review.py (Diff revision 2)
       
       
      Show all issues

      This should be in the imperative mood ("Return whether" rather than "Returns whether")

    5. reviewboard/reviews/models/review.py (Diff revision 2)
       
       
       
       
       
      Show all issues

      This can easily fit all on one line.

    6. 
        
    gmyers
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
    2. 
        
    david
    1. Just one tiny nit:

    2. reviewboard/reviews/models/review.py (Diff revision 3)
       
       
       
      Show all issues

      The description should be on the line after the type:

      bool:
      ``True`` if the review contains any comments/issues and
      ``False`` otherwise.
      
    3. 
        
    gmyers
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
    2. 
        
    brennie
    1. 
        
    2. reviewboard/reviews/models/review.py (Diff revisions 1 - 4)
       
       
      Show all issues

      Single space after a period.

      "Whether or not"

      "with open issues only"

      1. I'll take care of the first two. With respect to the third, any concern that this could cause confusion about what is being checked here, between a comment with issue_opened = True and one with issue_status = open (I admittedly don't have the greatest sense of the distinction between these fields)?

      2. The issue_status field only applies if issue_opened is True. Probably we should be specific and say "check for comments where ``issue_opened`` is ``True``"

    3. 
        
    gmyers
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          reviewboard/notifications/email.py
          reviewboard/notifications/tests.py
          reviewboard/reviews/models/review.py
      
      Ignored Files:
          docs/manual/extending/extensions/hooks/comment-detail-display-hook.rst
          reviewboard/templates/notifications/review_email.txt
          reviewboard/templates/notifications/review_email.html
      
      
    2. 
        
    gmyers
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-3.0.x (36d91a6)