Merge lp:~michael.nelson/launchpad/635005-difference-details-2 into lp:launchpad/db-devel

Proposed by Michael Nelson
Status: Merged
Approved by: Michael Nelson
Approved revision: no longer in the source branch.
Merged at revision: 9813
Proposed branch: lp:~michael.nelson/launchpad/635005-difference-details-2
Merge into: lp:launchpad/db-devel
Diff against target: 958 lines (+452/-101)
21 files modified
lib/canonical/launchpad/interfaces/_schema_circular_imports.py (+4/-0)
lib/lp/app/templates/base-layout-macros.pt (+2/-0)
lib/lp/code/browser/branchmergeproposal.py (+9/-2)
lib/lp/code/browser/codereviewcomment.py (+39/-35)
lib/lp/code/browser/configure.zcml (+10/-3)
lib/lp/code/browser/tests/test_branchmergeproposal.py (+21/-2)
lib/lp/code/browser/tests/test_codereviewcomment.py (+26/-9)
lib/lp/code/templates/codereviewcomment-body.pt (+2/-2)
lib/lp/code/templates/codereviewcomment-header.pt (+3/-3)
lib/lp/registry/browser/configure.zcml (+4/-1)
lib/lp/registry/browser/distroseriesdifference.py (+40/-6)
lib/lp/registry/browser/tests/test_distroseriesdifference_views.py (+58/-13)
lib/lp/registry/browser/tests/test_series_views.py (+19/-0)
lib/lp/registry/javascript/distroseriesdifferences_details.js (+86/-0)
lib/lp/registry/templates/distroseries-localdifferences.pt (+9/-2)
lib/lp/registry/templates/distroseriesdifference-listing-extra.pt (+31/-19)
lib/lp/registry/windmill/tests/test_distroseriesdifference_expander.py (+42/-0)
lib/lp/services/comments/browser/configure.zcml (+12/-4)
lib/lp/services/comments/interfaces/conversation.py (+18/-0)
lib/lp/services/comments/templates/comment-body.pt (+8/-0)
lib/lp/services/comments/templates/comment-header.pt (+9/-0)
To merge this branch: bzr merge lp:~michael.nelson/launchpad/635005-difference-details-2
Reviewer Review Type Date Requested Status
Henning Eggers (community) code Approve
Curtis Hovey (community) ui Approve
Abel Deuring (community) code Approve
Review via email: mp+35640@code.launchpad.net

Commit message

Add extra details of DistroSeriesDifferences via Javascript.

Description of the change

Overview
========

This branch adds comment rendering to the extra-details template for DistroSeriesDifferences and hooks them up to the DistroSeriesDifference list like this:

https://devpad.canonical.com/~michaeln/tmp/distroseriesdifference-extra.ogv

Details
=======
This branch adds and tests the rendering of comments on the distroseriesdifference-listing-extra.pt template, and then adds the non-js link to this page from the distroseries-localdifferences.pt template.

It then adds JS to enhance this by loading the snippet and adding it inline as an expanded table row.

Note: A large part of the diff below is adding a default view and templates for the lp.services.comments system. This involved updating IComment with all the common comment attributes, and updating the code views so that their display comment model also provides IComment.

To test
=======
bin/test -vv -m test_distroseriesdifference_views -m test_series_views -m test_codereviewcomment

Windmill:
bin/test -vvm test_distroseriesdifference_expander

To demo
=======
Run http://pastebin.ubuntu.com/494656/ in bin/iharness and then open
https://launchpad.dev/ubuntu/hoary/+localpackagediffs

To post a comment you must log in.
Revision history for this message
Henning Eggers (henninge) wrote :

Thank you for that great screencast. I just installed "recordmydesktop", too. ;-)

As you mentioned and we discussed in IRC you should use the same style for comments as we have elsewhere on Launchpad. But feel free to propose to change our comments to contain (smaller) logos/head shots of uses. ;-)

Also discussed: The items in the list of available diffs should be preceded by a download icon and the list should be indented. I am also wondering (not discussed) if this section could not be reworded like this:

Differences from last common version:

 * Derived version: 1.15-2ubuntu1derilucid2 (1.2kB)
 * Base version: 1.17-1 (0.5kB)

I think this is clearer and has less noise. The word "package" here was noise, too, because we are already in a table row that is about this package. I am just wondering if the whole line should be the link or just the version number. In the latter case the download icon would end up in the middle of the line, which might not be desirable. Maybe you can play around with that a bit to see what looks best.

I am not approving this yet because I'd like to see the outcome of this and also the inclusion of the standard LP comments first.

review: Needs Fixing (ui*)
Revision history for this message
Michael Nelson (michael.nelson) wrote :

On Thu, Sep 16, 2010 at 1:06 PM, Henning Eggers
<email address hidden> wrote:
> Review: Needs Fixing ui*
> Thank you for that great screencast. I just installed "recordmydesktop", too. ;-)
>
> As you mentioned and we discussed in IRC you should use the same style for comments as we have elsewhere on Launchpad. But feel free to propose to change our comments to contain (smaller) logos/head shots of uses. ;-)

Yep. Also, I've just found lp.services.comments too, so I'll probably
refactor a bit to use that.

>
> Also discussed: The items in the list of available diffs should be preceded by a download icon and the list should be indented.

Yes for the icon, but when the actual diffs are displayed (perhaps not
when they need to be requested first). And +1 for the indentation too.

> I am also wondering (not discussed) if this section could not be reworded like this:
>
> Differences from last common version:
>
>  * Derived version: 1.15-2ubuntu1derilucid2 (1.2kB)
>  * Base version: 1.17-1 (0.5kB)
>
> I think this is clearer and has less noise. The word "package" here was noise, too, because we are already in a table row that is about this package. I am just wondering if the whole line should be the link or just the version number. In the latter case the download icon would end up in the middle of the line, which might not be desirable. Maybe you can play around with that a bit to see what looks best.

Sounds good. I'll hopefully have something tomorrow morning :)

Revision history for this message
Henning Eggers (henninge) wrote :

The comments section looks good now and the wording for the differences is perfect. Thank you. You fixed the "binary descriptions" sections, too, which I had forgotten to mention. Good job! I guess I was wrong about the idention but this is fine, too. I'd still like the download icon but will not hold the review on this. Let's hear Paul's take on this ... ;-)

Thank you very much again!

Paul, I think I should be in "Launchpad UI Reviewers", shouldn't I?

review: Approve (ui*)
Revision history for this message
Michael Nelson (michael.nelson) wrote :

On Fri, Sep 17, 2010 at 11:04 AM, Henning Eggers
<email address hidden> wrote:
> Review: Approve ui*
> The comments section looks good now and the wording for the differences is perfect. Thank you. You fixed the "binary descriptions" sections, too, which I had forgotten to mention. Good job!  I guess I was wrong about the idention but this is fine, too. I'd still like the download icon but will not hold the review on this. Let's hear Paul's take on this ... ;-)

Thanks Henning. Just to be clear, I also want the download icon - but
only when there is something to download. The current UI is
representing the state where we *could* generate that PackageDiff if
the user requests it, but I need to add the JS to do that. Once the
diff has been generated I'm all for it being displayed with the icon
(and updating the similar link on PPA packages to do the same).

@Paul: I'm actually updating the lp.services.comments stuff, adding
some generic templates/views. I'll hopefully have pushed this by the
time you check, so in addition to the UI review, would you mind
glancing over the lp.services.comments changes I'm adding to make sure
it's inline with what the code team envisaged. Thanks.

Revision history for this message
Abel Deuring (adeuring) wrote :

nice work!

review: Approve (code)
Revision history for this message
Curtis Hovey (sinzui) wrote :

This is excellent. I have no remarks; well done Henning.

review: Approve (ui)
Revision history for this message
Michael Nelson (michael.nelson) wrote :

I had to make the following changes to ensure code's use of comments renders with their own templates, rather than the default ones for IComment:

http://pastebin.ubuntu.com/496936/

As well as ensuring the zcml links up the correct template, it also ensures that the code comment classes (CodeReviewDisplayComment and CodeReviewNewRevisions) do implement the new IComment iface.

Revision history for this message
Henning Eggers (henninge) wrote :

The incremental diff looks good to me. ;-) Placing the marker interface in the browser code seems to be common practice.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/interfaces/_schema_circular_imports.py'
--- lib/canonical/launchpad/interfaces/_schema_circular_imports.py 2010-08-27 11:19:54 +0000
+++ lib/canonical/launchpad/interfaces/_schema_circular_imports.py 2010-09-21 11:03:45 +0000
@@ -89,6 +89,7 @@
89 IStructuralSubscription,89 IStructuralSubscription,
90 IStructuralSubscriptionTarget,90 IStructuralSubscriptionTarget,
91 )91 )
92from lp.services.comments.interfaces.conversation import IComment
92from lp.soyuz.enums import (93from lp.soyuz.enums import (
93 PackagePublishingStatus,94 PackagePublishingStatus,
94 PackageUploadCustomFormat,95 PackageUploadCustomFormat,
@@ -321,6 +322,9 @@
321IBuildFarmJob['status'].vocabulary = BuildStatus322IBuildFarmJob['status'].vocabulary = BuildStatus
322IBuildFarmJob['buildqueue_record'].schema = IBuildQueue323IBuildFarmJob['buildqueue_record'].schema = IBuildQueue
323324
325# IComment
326IComment['comment_author'].schema = IPerson
327
324# IDistribution328# IDistribution
325IDistribution['series'].value_type.schema = IDistroSeries329IDistribution['series'].value_type.schema = IDistroSeries
326patch_reference_property(330patch_reference_property(
327331
=== modified file 'lib/lp/app/templates/base-layout-macros.pt'
--- lib/lp/app/templates/base-layout-macros.pt 2010-08-20 13:33:51 +0000
+++ lib/lp/app/templates/base-layout-macros.pt 2010-09-21 11:03:45 +0000
@@ -183,6 +183,8 @@
183 <script type="text/javascript"183 <script type="text/javascript"
184 tal:attributes="src string:${lp_js}/bugs/bugtracker_overlay.js"></script>184 tal:attributes="src string:${lp_js}/bugs/bugtracker_overlay.js"></script>
185 <script type="text/javascript"185 <script type="text/javascript"
186 tal:attributes="src string:${lp_js}/registry/distroseriesdifferences_details.js"></script>
187 <script type="text/javascript"
186 tal:attributes="src string:${lp_js}/registry/milestoneoverlay.js"></script>188 tal:attributes="src string:${lp_js}/registry/milestoneoverlay.js"></script>
187 <script type="text/javascript"189 <script type="text/javascript"
188 tal:attributes="src string:${lp_js}/registry/milestonetable.js"></script>190 tal:attributes="src string:${lp_js}/registry/milestonetable.js"></script>
189191
=== modified file 'lib/lp/code/browser/branchmergeproposal.py'
--- lib/lp/code/browser/branchmergeproposal.py 2010-08-24 10:45:57 +0000
+++ lib/lp/code/browser/branchmergeproposal.py 2010-09-21 11:03:45 +0000
@@ -547,7 +547,7 @@
547 return diff_text.count('\n') >= config.diff.max_format_lines547 return diff_text.count('\n') >= config.diff.max_format_lines
548548
549549
550class ICodeReviewNewRevisions(Interface):550class ICodeReviewNewRevisions(IComment):
551 """Marker interface used to register views for CodeReviewNewRevisions."""551 """Marker interface used to register views for CodeReviewNewRevisions."""
552552
553553
@@ -557,7 +557,7 @@
557 Each object instance represents a number of revisions scanned at a557 Each object instance represents a number of revisions scanned at a
558 particular time.558 particular time.
559 """559 """
560 implements(IComment, ICodeReviewNewRevisions)560 implements(ICodeReviewNewRevisions)
561561
562 def __init__(self, revisions, date, branch):562 def __init__(self, revisions, date, branch):
563 self.revisions = revisions563 self.revisions = revisions
@@ -567,6 +567,13 @@
567 # The date attribute is used to sort the comments in the conversation.567 # The date attribute is used to sort the comments in the conversation.
568 self.date = date568 self.date = date
569569
570 # Other standard IComment attributes are not used.
571 self.extra_css_class = None
572 self.comment_author = None
573 self.body_text = None
574 self.comment_date = None
575 self.display_attachments = False
576
570577
571class CodeReviewNewRevisionsView(LaunchpadView):578class CodeReviewNewRevisionsView(LaunchpadView):
572 """The view for rendering the new revisions."""579 """The view for rendering the new revisions."""
573580
=== modified file 'lib/lp/code/browser/codereviewcomment.py'
--- lib/lp/code/browser/codereviewcomment.py 2010-08-24 10:45:57 +0000
+++ lib/lp/code/browser/codereviewcomment.py 2010-09-21 11:03:45 +0000
@@ -43,6 +43,10 @@
43from lp.services.propertycache import cachedproperty43from lp.services.propertycache import cachedproperty
4444
4545
46class ICodeReviewDisplayComment(IComment, ICodeReviewComment):
47 """Marker interface for displaying code review comments."""
48
49
46class CodeReviewDisplayComment:50class CodeReviewDisplayComment:
47 """A code review comment or activity or both.51 """A code review comment or activity or both.
4852
@@ -51,7 +55,7 @@
51 only code in the model itself.55 only code in the model itself.
52 """56 """
5357
54 implements(IComment)58 implements(ICodeReviewDisplayComment)
5559
56 delegates(ICodeReviewComment, 'comment')60 delegates(ICodeReviewComment, 'comment')
5761
@@ -70,6 +74,40 @@
70 else:74 else:
71 return ''75 return ''
7276
77 @cachedproperty
78 def comment_author(self):
79 """The author of the comment."""
80 return self.comment.message.owner
81
82 @cachedproperty
83 def has_body(self):
84 """Is there body text?"""
85 return bool(self.body_text)
86
87 @cachedproperty
88 def body_text(self):
89 """Get the body text for the message."""
90 return self.comment.message_body
91
92 @cachedproperty
93 def comment_date(self):
94 """The date of the comment."""
95 return self.comment.message.datecreated
96
97 @cachedproperty
98 def all_attachments(self):
99 return self.comment.getAttachments()
100
101 @cachedproperty
102 def display_attachments(self):
103 # Attachments to show.
104 return [DiffAttachment(alias) for alias in self.all_attachments[0]]
105
106 @cachedproperty
107 def other_attachments(self):
108 # Attachments to not show.
109 return self.all_attachments[1]
110
73111
74class CodeReviewCommentPrimaryContext:112class CodeReviewCommentPrimaryContext:
75 """The primary context is the comment is that of the source branch."""113 """The primary context is the comment is that of the source branch."""
@@ -132,45 +170,11 @@
132 """The decorated code review comment."""170 """The decorated code review comment."""
133 return CodeReviewDisplayComment(self.context)171 return CodeReviewDisplayComment(self.context)
134172
135 @cachedproperty
136 def comment_author(self):
137 """The author of the comment."""
138 return self.context.message.owner
139
140 @cachedproperty
141 def has_body(self):
142 """Is there body text?"""
143 return bool(self.body_text)
144
145 @cachedproperty
146 def body_text(self):
147 """Get the body text for the message."""
148 return self.context.message_body
149
150 @cachedproperty
151 def comment_date(self):
152 """The date of the comment."""
153 return self.context.message.datecreated
154
155 # Should the comment be shown in full?173 # Should the comment be shown in full?
156 full_comment = True174 full_comment = True
157 # Show comment expanders?175 # Show comment expanders?
158 show_expanders = False176 show_expanders = False
159177
160 @cachedproperty
161 def all_attachments(self):
162 return self.context.getAttachments()
163
164 @cachedproperty
165 def display_attachments(self):
166 # Attachments to show.
167 return [DiffAttachment(alias) for alias in self.all_attachments[0]]
168
169 @cachedproperty
170 def other_attachments(self):
171 # Attachments to not show.
172 return self.all_attachments[1]
173
174178
175class CodeReviewCommentSummary(CodeReviewCommentView):179class CodeReviewCommentSummary(CodeReviewCommentView):
176 """Summary view of a CodeReviewComment"""180 """Summary view of a CodeReviewComment"""
177181
=== modified file 'lib/lp/code/browser/configure.zcml'
--- lib/lp/code/browser/configure.zcml 2010-09-20 00:20:42 +0000
+++ lib/lp/code/browser/configure.zcml 2010-09-21 11:03:45 +0000
@@ -691,6 +691,16 @@
691 name="+index"691 name="+index"
692 template="../templates/codereviewcomment-index.pt"/>692 template="../templates/codereviewcomment-index.pt"/>
693 <browser:page693 <browser:page
694 name="+fragment"
695 template="../templates/codereviewcomment-fragment.pt"/>
696 </browser:pages>
697 <browser:pages
698 facet="branches"
699 for="lp.code.browser.codereviewcomment.ICodeReviewDisplayComment"
700 layer="lp.code.publisher.CodeLayer"
701 class="lp.code.browser.codereviewcomment.CodeReviewCommentView"
702 permission="zope.Public">
703 <browser:page
694 name="+comment-header"704 name="+comment-header"
695 template="../templates/codereviewcomment-header.pt"/>705 template="../templates/codereviewcomment-header.pt"/>
696 <browser:page706 <browser:page
@@ -699,9 +709,6 @@
699 <browser:page709 <browser:page
700 name="+comment-footer"710 name="+comment-footer"
701 template="../templates/codereviewcomment-footer.pt"/>711 template="../templates/codereviewcomment-footer.pt"/>
702 <browser:page
703 name="+fragment"
704 template="../templates/codereviewcomment-fragment.pt"/>
705 </browser:pages>712 </browser:pages>
706 <browser:pages713 <browser:pages
707 facet="branches"714 facet="branches"
708715
=== modified file 'lib/lp/code/browser/tests/test_branchmergeproposal.py'
--- lib/lp/code/browser/tests/test_branchmergeproposal.py 2010-08-22 21:34:16 +0000
+++ lib/lp/code/browser/tests/test_branchmergeproposal.py 2010-09-21 11:03:45 +0000
@@ -24,6 +24,7 @@
24from canonical.launchpad.database.message import MessageSet24from canonical.launchpad.database.message import MessageSet
25from canonical.launchpad.webapp.interfaces import IPrimaryContext25from canonical.launchpad.webapp.interfaces import IPrimaryContext
26from canonical.launchpad.webapp.servers import LaunchpadTestRequest26from canonical.launchpad.webapp.servers import LaunchpadTestRequest
27from canonical.launchpad.webapp.testing import verifyObject
27from canonical.testing import (28from canonical.testing import (
28 DatabaseFunctionalLayer,29 DatabaseFunctionalLayer,
29 LaunchpadFunctionalLayer,30 LaunchpadFunctionalLayer,
@@ -36,8 +37,10 @@
36 BranchMergeProposalMergedView,37 BranchMergeProposalMergedView,
37 BranchMergeProposalVoteView,38 BranchMergeProposalVoteView,
38 DecoratedCodeReviewVoteReference,39 DecoratedCodeReviewVoteReference,
40 ICodeReviewNewRevisions,
39 latest_proposals_for_each_branch,41 latest_proposals_for_each_branch,
40 )42 )
43from lp.code.browser.codereviewcomment import CodeReviewDisplayComment
41from lp.code.enums import (44from lp.code.enums import (
42 BranchMergeProposalStatus,45 BranchMergeProposalStatus,
43 CodeReviewVote,46 CodeReviewVote,
@@ -634,6 +637,21 @@
634 [revisions[2], revisions[3]]]637 [revisions[2], revisions[3]]]
635 self.assertRevisionGroups(bmp, expected_groups)638 self.assertRevisionGroups(bmp, expected_groups)
636639
640 def test_CodeReviewNewRevisions_implements_ICodeReviewNewRevisions(self):
641 # The browser helper class implements its interface.
642 review_date = datetime(2009, 9, 10, tzinfo=pytz.UTC)
643 revision_date = review_date + timedelta(days=1)
644 bmp = self.factory.makeBranchMergeProposal(
645 date_created=review_date)
646 revision = add_revision_to_branch(
647 self.factory, bmp.source_branch, revision_date)
648
649 view = create_initialized_view(bmp, '+index')
650 groups = view._getRevisionsSinceReviewStart()
651 new_revisions = groups[0]
652
653 self.assertTrue(verifyObject(ICodeReviewNewRevisions, new_revisions))
654
637 def test_include_superseded_comments(self):655 def test_include_superseded_comments(self):
638 for x, time in zip(range(3), time_counter()):656 for x, time in zip(range(3), time_counter()):
639 if x != 0:657 if x != 0:
@@ -767,7 +785,8 @@
767 body='testing',785 body='testing',
768 attachments=[('test.diff', 'text/plain', attachment_body)])786 attachments=[('test.diff', 'text/plain', attachment_body)])
769 message = MessageSet().fromEmail(msg.as_string())787 message = MessageSet().fromEmail(msg.as_string())
770 return bmp.createCommentFromMessage(message, None, None, msg)788 return CodeReviewDisplayComment(
789 bmp.createCommentFromMessage(message, None, None, msg))
771790
772 def test_nonascii_in_attachment_renders(self):791 def test_nonascii_in_attachment_renders(self):
773 # The view should render without errors.792 # The view should render without errors.
@@ -783,7 +802,7 @@
783 # Need to commit in order to read the diff out of the librarian.802 # Need to commit in order to read the diff out of the librarian.
784 transaction.commit()803 transaction.commit()
785 view = create_initialized_view(comment, '+comment-body')804 view = create_initialized_view(comment, '+comment-body')
786 [diff_attachment] = view.display_attachments805 [diff_attachment] = view.comment.display_attachments
787 self.assertEqual(u'\u2615', diff_attachment.diff_text)806 self.assertEqual(u'\u2615', diff_attachment.diff_text)
788807
789808
790809
=== modified file 'lib/lp/code/browser/tests/test_codereviewcomment.py'
--- lib/lp/code/browser/tests/test_codereviewcomment.py 2010-08-20 20:31:18 +0000
+++ lib/lp/code/browser/tests/test_codereviewcomment.py 2010-09-21 11:03:45 +0000
@@ -3,35 +3,52 @@
33
4"""Unit tests for CodeReviewComments."""4"""Unit tests for CodeReviewComments."""
55
6from __future__ import with_statement
7
6__metaclass__ = type8__metaclass__ = type
79
8import unittest10import unittest
911
10from canonical.launchpad.webapp.interfaces import IPrimaryContext12from canonical.launchpad.webapp.interfaces import IPrimaryContext
13from canonical.launchpad.webapp.testing import verifyObject
11from canonical.testing import DatabaseFunctionalLayer14from canonical.testing import DatabaseFunctionalLayer
15from lp.code.browser.codereviewcomment import (
16 CodeReviewDisplayComment,
17 ICodeReviewDisplayComment,
18 )
12from lp.testing import (19from lp.testing import (
13 login_person,20 person_logged_in,
14 TestCaseWithFactory,21 TestCaseWithFactory,
15 )22 )
1623
1724
18class TestCodeReviewCommentPrimaryContext(TestCaseWithFactory):25class TestCodeReviewComments(TestCaseWithFactory):
19 # Tests the adaptation of a code review comment into a primary context.
2026
21 layer = DatabaseFunctionalLayer27 layer = DatabaseFunctionalLayer
2228
23 def testPrimaryContext(self):29 def testPrimaryContext(self):
30 # Tests the adaptation of a code review comment into a primary
31 # context.
24 # We need a person to make a comment.32 # We need a person to make a comment.
25 commenter = self.factory.makePerson()33 with person_logged_in(self.factory.makePerson()):
26 login_person(commenter)34 # The primary context of a code review comment is the same
27 # The primary context of a code review comment is the same as the35 # as the primary context for the branch merge proposal that
28 # primary context for the branch merge proposal that the comment is36 # the comment is for.
29 # for.37 comment = self.factory.makeCodeReviewComment()
30 comment = self.factory.makeCodeReviewComment()38
31 self.assertEqual(39 self.assertEqual(
32 IPrimaryContext(comment).context,40 IPrimaryContext(comment).context,
33 IPrimaryContext(comment.branch_merge_proposal).context)41 IPrimaryContext(comment.branch_merge_proposal).context)
3442
43 def test_display_comment_provides_icodereviewdisplaycomment(self):
44 # The CodeReviewDisplayComment class provides IComment.
45 with person_logged_in(self.factory.makePerson()):
46 comment = self.factory.makeCodeReviewComment()
47
48 display_comment = CodeReviewDisplayComment(comment)
49
50 verifyObject(ICodeReviewDisplayComment, display_comment)
51
3552
36def test_suite():53def test_suite():
37 return unittest.TestLoader().loadTestsFromName(__name__)54 return unittest.TestLoader().loadTestsFromName(__name__)
3855
=== modified file 'lib/lp/code/templates/codereviewcomment-body.pt'
--- lib/lp/code/templates/codereviewcomment-body.pt 2010-04-16 04:20:43 +0000
+++ lib/lp/code/templates/codereviewcomment-body.pt 2010-09-21 11:03:45 +0000
@@ -3,9 +3,9 @@
3 xmlns:metal="http://xml.zope.org/namespaces/metal"3 xmlns:metal="http://xml.zope.org/namespaces/metal"
4 omit-tag="">4 omit-tag="">
55
6 <tal:message replace="structure view/body_text/fmt:obfuscate-email/fmt:nice_pre" />6 <tal:message replace="structure view/comment/body_text/fmt:obfuscate-email/fmt:nice_pre" />
77
8 <tal:good-attachments repeat="attachment view/display_attachments">8 <tal:good-attachments repeat="attachment view/comment/display_attachments">
9 <div class="boardComment attachment">9 <div class="boardComment attachment">
10 <div class="boardCommentDetails filename"><a tal:content="attachment/filename" tal:attributes="href attachment/getURL"/></div>10 <div class="boardCommentDetails filename"><a tal:content="attachment/filename" tal:attributes="href attachment/getURL"/></div>
11 <div class="boardCommentBody attachmentBody" tal:content="structure attachment/diff_text/fmt:diff"/>11 <div class="boardCommentBody attachmentBody" tal:content="structure attachment/diff_text/fmt:diff"/>
1212
=== modified file 'lib/lp/code/templates/codereviewcomment-header.pt'
--- lib/lp/code/templates/codereviewcomment-header.pt 2010-02-18 16:40:09 +0000
+++ lib/lp/code/templates/codereviewcomment-header.pt 2010-09-21 11:03:45 +0000
@@ -3,9 +3,9 @@
3 xmlns:metal="http://xml.zope.org/namespaces/metal"3 xmlns:metal="http://xml.zope.org/namespaces/metal"
4 omit-tag="">4 omit-tag="">
55
6 <tal:author replace="structure view/comment_author/fmt:link:mainsite"/>6 <tal:author replace="structure context/comment_author/fmt:link:mainsite"/>
7 <tal:has-body condition="view/has_body">wrote</tal:has-body>7 <tal:has-body condition="context/has_body">wrote</tal:has-body>
8 <tal:date replace="view/comment_date/fmt:displaydate" />8 <tal:date replace="context/comment_date/fmt:displaydate" />
9 <span tal:condition="context/from_superseded" class="sprite warning-icon"9 <span tal:condition="context/from_superseded" class="sprite warning-icon"
10 style="float: right">Posted in <a10 style="float: right">Posted in <a
11 tal:attributes="href context/branch_merge_proposal/fmt:url">a11 tal:attributes="href context/branch_merge_proposal/fmt:url">a
1212
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml 2010-09-13 10:04:20 +0000
+++ lib/lp/registry/browser/configure.zcml 2010-09-21 11:03:45 +0000
@@ -151,7 +151,7 @@
151 permission="zope.Public"/>151 permission="zope.Public"/>
152 <browser:url152 <browser:url
153 for="lp.registry.interfaces.distroseriesdifference.IDistroSeriesDifference"153 for="lp.registry.interfaces.distroseriesdifference.IDistroSeriesDifference"
154 path_expression="string:+difference/${difference/source_package_name}"154 path_expression="string:+difference/${source_package_name/name}"
155 rootsite="mainsite"155 rootsite="mainsite"
156 attribute_to_parent="derived_series"/>156 attribute_to_parent="derived_series"/>
157 <browser:page157 <browser:page
@@ -160,6 +160,9 @@
160 class="lp.registry.browser.distroseriesdifference.DistroSeriesDifferenceView"160 class="lp.registry.browser.distroseriesdifference.DistroSeriesDifferenceView"
161 template="../templates/distroseriesdifference-listing-extra.pt"161 template="../templates/distroseriesdifference-listing-extra.pt"
162 permission="zope.Public"/>162 permission="zope.Public"/>
163 <browser:defaultView
164 for="lp.registry.interfaces.distroseriesdifference.IDistroSeriesDifference"
165 name="+listing-distroseries-extra"/>
163 <browser:menus166 <browser:menus
164 classes="167 classes="
165 DistroSeriesFacets168 DistroSeriesFacets
166169
=== modified file 'lib/lp/registry/browser/distroseriesdifference.py'
--- lib/lp/registry/browser/distroseriesdifference.py 2010-09-13 15:09:48 +0000
+++ lib/lp/registry/browser/distroseriesdifference.py 2010-09-21 11:03:45 +0000
@@ -8,14 +8,22 @@
8 'DistroSeriesDifferenceView',8 'DistroSeriesDifferenceView',
9 ]9 ]
1010
11from zope.interface import implements
12
11from canonical.launchpad.webapp.publisher import LaunchpadView13from canonical.launchpad.webapp.publisher import LaunchpadView
14from lp.services.comments.interfaces.conversation import (
15 IComment,
16 IConversation,
17 )
1218
1319
14class DistroSeriesDifferenceView(LaunchpadView):20class DistroSeriesDifferenceView(LaunchpadView):
1521
22 implements(IConversation)
23
16 @property24 @property
17 def summary(self):25 def binary_summaries(self):
18 """Return the summary of the related source package."""26 """Return the summary of the related binary packages."""
19 source_pub = None27 source_pub = None
20 if self.context.source_pub is not None:28 if self.context.source_pub is not None:
21 source_pub = self.context.source_pub29 source_pub = self.context.source_pub
@@ -23,7 +31,33 @@
23 source_pub = self.context.parent_source_pub31 source_pub = self.context.parent_source_pub
2432
25 if source_pub is not None:33 if source_pub is not None:
26 return source_pub.meta_sourcepackage.summary34 summary = source_pub.meta_sourcepackage.summary
27 else:35 if summary:
28 return None36 return summary.split('\n')
2937
38 return None
39
40 @property
41 def comments(self):
42 """See `IConversation`."""
43 # Could use a generator here?
44 return [
45 DistroSeriesDifferenceDisplayComment(comment) for
46 comment in self.context.getComments()]
47
48
49class DistroSeriesDifferenceDisplayComment:
50 """Used simply to provide `IComment` for rendering."""
51 implements(IComment)
52
53 has_body = True
54 has_footer = False
55 display_attachments = False
56 extra_css_class = ''
57
58 def __init__(self, comment):
59 """Setup the attributes required by `IComment`."""
60 self.message_body = comment.comment
61 self.comment_author = comment.message.owner
62 self.comment_date = comment.message.datecreated
63 self.body_text = comment.comment
3064
=== modified file 'lib/lp/registry/browser/tests/test_distroseriesdifference_views.py'
--- lib/lp/registry/browser/tests/test_distroseriesdifference_views.py 2010-09-14 13:37:17 +0000
+++ lib/lp/registry/browser/tests/test_distroseriesdifference_views.py 2010-09-21 11:03:45 +0000
@@ -10,12 +10,20 @@
10from BeautifulSoup import BeautifulSoup10from BeautifulSoup import BeautifulSoup
11from zope.component import getUtility11from zope.component import getUtility
1212
13from canonical.launchpad.webapp.testing import verifyObject
13from canonical.testing import (14from canonical.testing import (
14 DatabaseFunctionalLayer,15 DatabaseFunctionalLayer,
15 LaunchpadFunctionalLayer,16 LaunchpadFunctionalLayer,
16 )17 )
18from lp.registry.browser.distroseriesdifference import (
19 DistroSeriesDifferenceDisplayComment,
20 )
17from lp.registry.enum import DistroSeriesDifferenceType21from lp.registry.enum import DistroSeriesDifferenceType
18from lp.registry.interfaces.distroseriesdifference import IDistroSeriesDifferenceSource22from lp.registry.interfaces.distroseriesdifference import IDistroSeriesDifferenceSource
23from lp.services.comments.interfaces.conversation import (
24 IComment,
25 IConversation,
26 )
19from lp.soyuz.enums import PackagePublishingStatus27from lp.soyuz.enums import PackagePublishingStatus
20from lp.soyuz.tests.test_publishing import SoyuzTestPublisher28from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
21from lp.testing import (29from lp.testing import (
@@ -30,10 +38,28 @@
3038
31 layer = DatabaseFunctionalLayer39 layer = DatabaseFunctionalLayer
3240
41 def test_provides_conversation(self):
42 # The DSDView provides a conversation implementation.
43 ds_diff = self.factory.makeDistroSeriesDifference()
44
45 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')
46 self.assertTrue(verifyObject(IConversation, view))
47
48 def test_comment_for_display_provides_icomment(self):
49 # The DSDDisplayComment browser object provides IComment.
50 ds_diff = self.factory.makeDistroSeriesDifference()
51 owner = ds_diff.derived_series.owner
52 with person_logged_in(owner):
53 comment = ds_diff.addComment(owner, "I'm working on this.")
54 comment_for_display = DistroSeriesDifferenceDisplayComment(comment)
55
56 self.assertTrue(verifyObject(IComment, comment_for_display))
57
33 def addSummaryToDifference(self, distro_series_difference):58 def addSummaryToDifference(self, distro_series_difference):
34 """Helper that adds binaries with summary info to the source pubs."""59 """Helper that adds binaries with summary info to the source pubs."""
35 distro_series = distro_series_difference.derived_series60 distro_series = distro_series_difference.derived_series
36 source_package_name_str = distro_series_difference.source_package_name.name61 source_package_name_str = (
62 distro_series_difference.source_package_name.name)
37 stp = SoyuzTestPublisher()63 stp = SoyuzTestPublisher()
3864
39 if distro_series_difference.difference_type == (65 if distro_series_difference.difference_type == (
@@ -52,7 +78,7 @@
52 distro_series, source_package_name_str)78 distro_series, source_package_name_str)
53 return ds_diff79 return ds_diff
5480
55 def test_summary_for_source_pub(self):81 def test_binary_summaries_for_source_pub(self):
56 # For packages unique to the derived series (or different82 # For packages unique to the derived series (or different
57 # versions) the summary is based on the derived source pub.83 # versions) the summary is based on the derived source pub.
58 ds_diff = self.factory.makeDistroSeriesDifference()84 ds_diff = self.factory.makeDistroSeriesDifference()
@@ -60,11 +86,13 @@
6086
61 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')87 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')
6288
63 self.assertIsNot(None, view.summary)89 self.assertIsNot(None, view.binary_summaries)
64 self.assertEqual(90 self.assertEqual([
65 ds_diff.source_pub.meta_sourcepackage.summary, view.summary)91 u'flubber-bin: summary for flubber-bin',
92 u'flubber-lib: summary for flubber-lib',
93 ], view.binary_summaries)
6694
67 def test_summary_for_missing_difference(self):95 def test_binary_summaries_for_missing_difference(self):
68 # For packages only in the parent series, the summary is based96 # For packages only in the parent series, the summary is based
69 # on the parent publication.97 # on the parent publication.
70 ds_diff = self.factory.makeDistroSeriesDifference(98 ds_diff = self.factory.makeDistroSeriesDifference(
@@ -74,12 +102,13 @@
74102
75 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')103 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')
76104
77 self.assertIsNot(None, view.summary)105 self.assertIsNot(None, view.binary_summaries)
78 self.assertEqual(106 self.assertEqual([
79 ds_diff.parent_source_pub.meta_sourcepackage.summary,107 u'flubber-bin: summary for flubber-bin',
80 view.summary)108 u'flubber-lib: summary for flubber-lib',
109 ], view.binary_summaries)
81110
82 def test_summary_no_pubs(self):111 def test_binary_summaries_no_pubs(self):
83 # If the difference has been resolved by removing packages then112 # If the difference has been resolved by removing packages then
84 # there will not be a summary.113 # there will not be a summary.
85 ds_diff = self.factory.makeDistroSeriesDifference(114 ds_diff = self.factory.makeDistroSeriesDifference(
@@ -93,7 +122,7 @@
93122
94 self.assertIs(None, ds_diff.parent_source_pub)123 self.assertIs(None, ds_diff.parent_source_pub)
95 self.assertIs(None, ds_diff.source_pub)124 self.assertIs(None, ds_diff.source_pub)
96 self.assertIs(None, view.summary)125 self.assertIs(None, view.binary_summaries)
97126
98127
99class DistroSeriesDifferenceTemplateTestCase(TestCaseWithFactory):128class DistroSeriesDifferenceTemplateTestCase(TestCaseWithFactory):
@@ -103,7 +132,7 @@
103 def number_of_request_diff_texts(self, html):132 def number_of_request_diff_texts(self, html):
104 """Check that the html doesn't include the request diff text."""133 """Check that the html doesn't include the request diff text."""
105 soup = BeautifulSoup(html)134 soup = BeautifulSoup(html)
106 return len(soup.findAll('dd', 'request-derived-diff'))135 return len(soup.findAll('li', 'request-derived-diff'))
107136
108 def contains_one_link_to_diff(self, html, package_diff):137 def contains_one_link_to_diff(self, html, package_diff):
109 """Return whether the html contains a link to the diff content."""138 """Return whether the html contains a link to the diff content."""
@@ -170,3 +199,19 @@
170199
171 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')200 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')
172 self.assertEqual(1, self.number_of_request_diff_texts(view()))201 self.assertEqual(1, self.number_of_request_diff_texts(view()))
202
203 def test_comments_rendered(self):
204 # If there are comments on the difference, they are rendered.
205 ds_diff = self.factory.makeDistroSeriesDifference()
206 owner = ds_diff.derived_series.owner
207 with person_logged_in(owner):
208 ds_diff.addComment(owner, "I'm working on this.")
209 ds_diff.addComment(owner, "Here's another comment.")
210
211 view = create_initialized_view(ds_diff, '+listing-distroseries-extra')
212 soup = BeautifulSoup(view())
213
214 self.assertEqual(
215 1, len(soup.findAll('pre', text="I'm working on this.")))
216 self.assertEqual(
217 1, len(soup.findAll('pre', text="Here's another comment.")))
173218
=== modified file 'lib/lp/registry/browser/tests/test_series_views.py'
--- lib/lp/registry/browser/tests/test_series_views.py 2010-09-08 07:53:06 +0000
+++ lib/lp/registry/browser/tests/test_series_views.py 2010-09-21 11:03:45 +0000
@@ -181,6 +181,25 @@
181 self.assertIn("Latest comment", unicode(rows[0]))181 self.assertIn("Latest comment", unicode(rows[0]))
182 self.assertNotIn("Earlier comment", unicode(rows[0]))182 self.assertNotIn("Earlier comment", unicode(rows[0]))
183183
184 def test_diff_row_links_to_extra_details(self):
185 # The source package name links to the difference details.
186 derived_series = self.makeDerivedSeries(
187 parent_name='lucid', derived_name='derilucid')
188 difference = self.factory.makeDistroSeriesDifference(
189 derived_series=derived_series)
190
191 self.setDerivedSeriesUIFeatureFlag()
192 view = create_initialized_view(
193 derived_series, '+localpackagediffs')
194 soup = BeautifulSoup(view())
195 diff_table = soup.find('table', {'class': 'listing'})
196 row = diff_table.tbody.findAll('tr')[0]
197
198 href = canonical_url(difference).replace('http://launchpad.dev', '')
199 links = row.findAll('a', href=href)
200 self.assertEqual(1, len(links))
201 self.assertEqual(difference.source_package_name.name, links[0].string)
202
184203
185class TestMilestoneBatchNavigatorAttribute(TestCaseWithFactory):204class TestMilestoneBatchNavigatorAttribute(TestCaseWithFactory):
186 """Test the series.milestone_batch_navigator attribute."""205 """Test the series.milestone_batch_navigator attribute."""
187206
=== added file 'lib/lp/registry/javascript/distroseriesdifferences_details.js'
--- lib/lp/registry/javascript/distroseriesdifferences_details.js 1970-01-01 00:00:00 +0000
+++ lib/lp/registry/javascript/distroseriesdifferences_details.js 2010-09-21 11:03:45 +0000
@@ -0,0 +1,86 @@
1/* Copyright 2010 Canonical Ltd. This software is licensed under the
2 * GNU Affero General Public License version 3 (see the file LICENSE).
3 *
4 * Enhancements for the distroseries differences page.
5 *
6 * @module registry
7 * @submodule distroseriesdifferences_details
8 * @requires io-base, lp.soyuz.base
9 */
10YUI.add('lp.registry.distroseriesdifferences_details', function(Y) {
11
12var namespace = Y.namespace('lp.registry.distroseriesdifferences_details');
13
14/*
15 * Setup the expandable rows for each difference.
16 *
17 * @method setup_expandable_rows
18 */
19namespace.setup_expandable_rows = function() {
20 var start_update = function(uri, container) {
21
22 var in_progress_message = Y.lp.soyuz.base.makeInProgressNode(
23 'Fetching difference details ...')
24 container.insert(in_progress_message, 'replace');
25
26 var config = {
27 on: {
28 'success': function(transaction_id, response, args) {
29 args.container.set(
30 'innerHTML', response.responseText);
31 // Change to insert(,'replace)
32 },
33 'failure': function(transaction_id, response, args){
34 var retry_handler = function(e) {
35 e.preventDefault();
36 start_update(args.uri, args.container);
37 };
38 var failure_message = Y.lp.soyuz.base.makeFailureNode(
39 'Failed to fetch difference details.',
40 retry_handler);
41 args.container.insert(failure_message, 'replace');
42
43 var anim = Y.lazr.anim.red_flash({
44 node: args.container
45 });
46 anim.run();
47 }
48 },
49 arguments: {
50 'container': container,
51 'uri': uri
52 }
53 };
54 Y.io(uri, config);
55
56 };
57
58 var expander_handler = function(e) {
59 e.preventDefault();
60 var toggle = e.currentTarget;
61 var row = toggle.ancestor('tr');
62 toggle.toggleClass('treeCollapsed').toggleClass('treeExpanded');
63
64 // Only insert if there isn't already a container row there.
65 next_row = row.next();
66 if (next_row == null || !next_row.hasClass('diff-extra')) {
67 details_row = Y.Node.create(
68 '<table><tr class="diff-extra unseen"><td colspan="5"></td></tr></table>').one('tr');
69 row.insert(details_row, 'after');
70 var uri = toggle.get('href');
71 start_update(uri, details_row.one('td'));
72 } else {
73 details_row = next_row
74 }
75
76 details_row.toggleClass('unseen');
77
78 };
79 Y.all('table.listing a.toggle-extra').each(function(toggle){
80 toggle.addClass('treeCollapsed').addClass('sprite');
81 toggle.on("click", expander_handler);
82 })
83
84};
85
86}, "0.1", {"requires": ["io-base", "lp.soyuz.base"]});
087
=== modified file 'lib/lp/registry/templates/distroseries-localdifferences.pt'
--- lib/lp/registry/templates/distroseries-localdifferences.pt 2010-09-08 09:18:11 +0000
+++ lib/lp/registry/templates/distroseries-localdifferences.pt 2010-09-21 11:03:45 +0000
@@ -45,8 +45,8 @@
45 <tr tal:define="parent_source_pub difference/parent_source_pub;45 <tr tal:define="parent_source_pub difference/parent_source_pub;
46 source_pub difference/source_pub;46 source_pub difference/source_pub;
47 signer source_pub/sourcepackagerelease/uploader/fmt:link|nothing;">47 signer source_pub/sourcepackagerelease/uploader/fmt:link|nothing;">
48 <td><span48 <td><a tal:attributes="href difference/fmt:url" class="toggle-extra"
49 tal:replace="parent_source_pub/source_package_name">Foo</span>49 tal:content="parent_source_pub/source_package_name">Foo</a>
50 </td>50 </td>
51 <td><a tal:attributes="href parent_source_pub/sourcepackagerelease/fmt:url">51 <td><a tal:attributes="href parent_source_pub/sourcepackagerelease/fmt:url">
52 <tal:replace52 <tal:replace
@@ -79,6 +79,13 @@
79 </tbody>79 </tbody>
80 </table>80 </table>
81 </div>81 </div>
82<script type="text/javascript">
83LPS.use('lp.registry.distroseriesdifferences_details', function(Y) {
84 diff_module = Y.lp.registry.distroseriesdifferences_details
85
86 Y.on('domready', diff_module.setup_expandable_rows);
87});
88</script>
8289
83 </div>90 </div>
8491
8592
=== modified file 'lib/lp/registry/templates/distroseriesdifference-listing-extra.pt'
--- lib/lp/registry/templates/distroseriesdifference-listing-extra.pt 2010-09-14 13:37:17 +0000
+++ lib/lp/registry/templates/distroseriesdifference-listing-extra.pt 2010-09-21 11:03:45 +0000
@@ -4,31 +4,43 @@
4 xmlns:i18n="http://xml.zope.org/namespaces/i18n"4 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
5 i18n:domain="launchpad">5 i18n:domain="launchpad">
6 <dl>6 <dl>
7 <dt>Description:</dt>7 <dt>Binary descriptions:</dt>
8 <dd><tal:description replace="view/summary" /></dd>8 <dd><ul>
9 <li tal:repeat="summary view/binary_summaries">
10 <tal:description replace="summary" /></li>
11 </ul></dd>
9 <dt>Last common version:</dt>12 <dt>Last common version:</dt>
10 <dd>Not implemented.</dd>13 <dd>Not implemented.</dd>
11 <dt>Package differences:</dt>14 <dt>Differences from last common version:</dt>
12 <tal:source-diff-option condition="context/source_pub">15 <dd>
13 <dd tal:condition="context/package_diff"16 <ul>
14 tal:content="structure context/package_diff/fmt:link">17 <tal:source-diff-option condition="context/source_pub">
15 <a>link to a diff</a></dd>18 <li tal:condition="context/package_diff"
16 <dd tal:condition="not: context/package_diff" class="request-derived-diff">19 tal:content="structure context/package_diff/fmt:link">
17 Base version to derived <span20 <a>link to a diff</a></li>
21 <li tal:condition="not: context/package_diff" class="request-derived-diff">
22 <span tal:replace="context/derived_series/displayname">
23 Derilucid</span> version: <span
18 tal:replace="context/source_version">1.2.3</span>24 tal:replace="context/source_version">1.2.3</span>
19 </dd>25 </li>
20 </tal:source-diff-option>26 </tal:source-diff-option>
2127
22 <tal:parent-diff-option condition="context/parent_source_pub">28 <tal:parent-diff-option condition="context/parent_source_pub">
23 <dd tal:condition="context/parent_package_diff"29 <li tal:condition="context/parent_package_diff"
24 tal:content="structure context/parent_package_diff/fmt:link">30 tal:content="structure context/parent_package_diff/fmt:link">
25 <a>link to a diff</a></dd>31 <a>link to a diff</a></li>
26 <dd tal:condition="not: context/parent_package_diff" class="request-derived-diff">32 <li tal:condition="not: context/parent_package_diff" class="request-derived-diff">
27 Base version to parent <span33 <span
28 tal:replace="context/parent_source_version">1.2.3</span>34 tal:replace="context/derived_series/parent_series/displayname">
35 Lucid</span> version: <span
36 tal:replace="context/parent_source_version">1.2.3</span>
37 </li>
38 </tal:parent-diff-option>
39 </ul>
29 </dd>40 </dd>
30 </tal:parent-diff-option>
31 </dl>41 </dl>
42
32 <h2>Comments:</h2>43 <h2>Comments:</h2>
44 <tal:conversation replace="structure view/@@+render"/>
3345
34</tal:root>46</tal:root>
3547
=== added file 'lib/lp/registry/windmill/tests/test_distroseriesdifference_expander.py'
--- lib/lp/registry/windmill/tests/test_distroseriesdifference_expander.py 1970-01-01 00:00:00 +0000
+++ lib/lp/registry/windmill/tests/test_distroseriesdifference_expander.py 2010-09-21 11:03:45 +0000
@@ -0,0 +1,42 @@
1# Copyright 2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4import transaction
5
6from canonical.launchpad.webapp.publisher import canonical_url
7from canonical.launchpad.windmill.testing import constants
8from lp.registry.windmill.testing import RegistryWindmillLayer
9from lp.services.features.model import FeatureFlag, getFeatureStore
10from lp.testing import WindmillTestCase
11
12
13class TestDistroSeriesDifferenceExtraJS(WindmillTestCase):
14 """Each listed source package can be expanded for extra information."""
15
16 layer = RegistryWindmillLayer
17
18 def setUp(self):
19 """Enable the feature and populate with data."""
20 super(TestDistroSeriesDifferenceExtraJS, self).setUp()
21 # First just ensure that the feature is enabled.
22 getFeatureStore().add(FeatureFlag(
23 scope=u'default', flag=u'soyuz.derived-series-ui.enabled',
24 value=u'on', priority=1))
25
26 # Setup the difference record.
27 self.diff = self.factory.makeDistroSeriesDifference(
28 source_package_name_str="foo", versions=dict(
29 derived='1.15-2ubuntu1derilucid2', parent='1.17-1'))
30 transaction.commit()
31
32 self.package_diffs_url = (
33 canonical_url(self.diff.derived_series) + '/+localpackagediffs')
34
35 def test_diff_extra_details_available(self):
36 """A successful request for the extra info updates the display."""
37 self.client.open(url=self.package_diffs_url)
38 self.client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
39 self.client.click(link=u'foo')
40 self.client.waits.forElement(
41 classname=u'diff-extra', timeout=constants.FOR_ELEMENT)
42
043
=== modified file 'lib/lp/services/comments/browser/configure.zcml'
--- lib/lp/services/comments/browser/configure.zcml 2009-07-17 02:25:09 +0000
+++ lib/lp/services/comments/browser/configure.zcml 2010-09-21 11:03:45 +0000
@@ -15,10 +15,18 @@
15 permission="zope.Public"15 permission="zope.Public"
16 template="../templates/conversation.pt"/>16 template="../templates/conversation.pt"/>
1717
18 <browser:page18 <browser:pages
19 name="+render"
20 for="lp.services.comments.interfaces.conversation.IComment"19 for="lp.services.comments.interfaces.conversation.IComment"
21 permission="zope.Public"20 permission="zope.Public">
22 template="../templates/comment.pt"/>21 <browser:page
22 name="+render"
23 template="../templates/comment.pt"/>
24 <browser:page
25 name="+comment-header"
26 template="../templates/comment-header.pt"/>
27 <browser:page
28 name="+comment-body"
29 template="../templates/comment-body.pt"/>
30 </browser:pages>
2331
24</configure>32</configure>
2533
=== modified file 'lib/lp/services/comments/interfaces/conversation.py'
--- lib/lp/services/comments/interfaces/conversation.py 2010-08-20 20:31:18 +0000
+++ lib/lp/services/comments/interfaces/conversation.py 2010-09-21 11:03:45 +0000
@@ -17,6 +17,8 @@
17from zope.interface import Interface17from zope.interface import Interface
18from zope.schema import (18from zope.schema import (
19 Bool,19 Bool,
20 Datetime,
21 Text,
20 TextLine,22 TextLine,
21 )23 )
2224
@@ -37,6 +39,22 @@
37 description=_("Does the comment have a footer?"),39 description=_("Does the comment have a footer?"),
38 readonly=True)40 readonly=True)
3941
42 body_text = Text(
43 description=_("The body text of the comment."),
44 readonly=True)
45
46 comment_author = Reference(
47 # Really IPerson.
48 Interface, title=_("The author of the comment."),
49 readonly=True)
50
51 comment_date = Datetime(
52 title=_('Comment date.'), readonly=True)
53
54 display_attachments = Bool(
55 description=_("Should attachments be displayed for this comment."),
56 readonly=True)
57
4058
41class IConversation(Interface):59class IConversation(Interface):
42 """A conversation has a number of comments."""60 """A conversation has a number of comments."""
4361
=== added file 'lib/lp/services/comments/templates/comment-body.pt'
--- lib/lp/services/comments/templates/comment-body.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/services/comments/templates/comment-body.pt 2010-09-21 11:03:45 +0000
@@ -0,0 +1,8 @@
1<tal:root
2 xmlns:tal="http://xml.zope.org/namespaces/tal"
3 xmlns:metal="http://xml.zope.org/namespaces/metal"
4 omit-tag="">
5
6 <tal:message replace="structure context/body_text/fmt:obfuscate-email/fmt:nice_pre" />
7
8</tal:root>
09
=== added file 'lib/lp/services/comments/templates/comment-header.pt'
--- lib/lp/services/comments/templates/comment-header.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/services/comments/templates/comment-header.pt 2010-09-21 11:03:45 +0000
@@ -0,0 +1,9 @@
1<tal:root
2 xmlns:tal="http://xml.zope.org/namespaces/tal"
3 xmlns:metal="http://xml.zope.org/namespaces/metal"
4 omit-tag="">
5
6 <tal:author replace="structure context/comment_author/fmt:link:mainsite"/>
7 <tal:has-body condition="context/has_body">wrote</tal:has-body>
8 <tal:date replace="context/comment_date/fmt:displaydate" />
9</tal:root>

Subscribers

People subscribed via source and target branches

to status/vote changes: