Merge lp:~james-w/launchpad/export-specification-bug-links into lp:launchpad

Proposed by James Westby
Status: Merged
Merged at revision: 12022
Proposed branch: lp:~james-w/launchpad/export-specification-bug-links
Merge into: lp:launchpad
Diff against target: 109 lines (+30/-5)
4 files modified
lib/lp/blueprints/interfaces/specification.py (+3/-1)
lib/lp/blueprints/tests/test_webservice.py (+11/-0)
lib/lp/bugs/interfaces/buglink.py (+14/-4)
lib/lp/bugs/interfaces/webservice.py (+2/-0)
To merge this branch: bzr merge lp:~james-w/launchpad/export-specification-bug-links
Reviewer Review Type Date Requested Status
Guilherme Salgado (community) code Approve
Linaro Infrastructure informational Pending
Review via email: mp+42426@code.launchpad.net

Commit message

[r=salgado][ui=none][bug=684378] Export specification/bug links over the API.

Description of the change

Hi,

Here is a small branch to export specification/bug links, which is the
last thing required to get the Ubuntu work items tracker using the API
for blueprints, rather than screen-scraping.

I'm not entirely sure that List->CollectionField doesn't change other
behavior, but lazr.restful doesn't do the right thing with List.

Also, I needed to add the inheritance to have lazr.restful add the bugs
property to the specifications. Previously the model just had
implements(IBugLinkTarget). I don't know if there is another way to achieve
that.

Thanks,

James

To post a comment you must log in.
Revision history for this message
Guilherme Salgado (salgado) wrote :
Download full text (4.8 KiB)

On Wed, 2010-12-01 at 22:24 +0000, James Westby wrote:
> You have been requested to review the proposed merge of lp:~james-w/launchpad/export-specification-bug-links into lp:launchpad.
>
> Hi,
>
> Here is a small branch to export specification/bug links, which is the
> last thing required to get the Ubuntu work items tracker using the API
> for blueprints, rather than screen-scraping.
>
> I'm not entirely sure that List->CollectionField doesn't change other
> behavior, but lazr.restful doesn't do the right thing with List.

I don't think we use the field you changed for constructing any forms,
so I'd be surprised if this has any side effects.

>
> Also, I needed to add the inheritance to have lazr.restful add the bugs
> property to the specifications. Previously the model just had
> implements(IBugLinkTarget). I don't know if there is another way to achieve
> that.

As we talked on IRC, I thought just exporting IBugLinkTarget as an entry
would make it work, but apparently it didn't?

> === modified file 'lib/lp/blueprints/interfaces/specification.py'
> --- lib/lp/blueprints/interfaces/specification.py 2010-12-01 12:54:42 +0000
> +++ lib/lp/blueprints/interfaces/specification.py 2010-12-01 22:24:03 +0000
> @@ -58,6 +58,7 @@
> IHasSpecifications,
> ISpecificationTarget,
> )
> +from lp.bugs.interfaces.buglink import IBugLinkTarget
> from lp.blueprints.interfaces.sprint import ISprint
> from lp.code.interfaces.branchlink import IHasLinkedBranches
> from lp.registry.interfaces.milestone import IMilestone
> @@ -529,7 +530,8 @@
> """Return the SpecificationBranch link for the branch, or None."""
>
>
> -class ISpecification(ISpecificationPublic, ISpecificationEditRestricted):
> +class ISpecification(ISpecificationPublic, ISpecificationEditRestricted,
> + IBugLinkTarget):
> """A Specification."""
>
> export_as_webservice_entry()
>
> === modified file 'lib/lp/blueprints/tests/test_webservice.py'
> --- lib/lp/blueprints/tests/test_webservice.py 2010-12-01 12:54:42 +0000
> +++ lib/lp/blueprints/tests/test_webservice.py 2010-12-01 22:24:03 +0000
> @@ -14,7 +14,11 @@
> )
> from lp.testing import (
> launchpadlib_for,
> +<<<<<<< TREE
> launchpadlib_for_anonymous,
> +=======
> + person_logged_in,
> +>>>>>>> MERGE-SOURCE
> TestCaseWithFactory,

A trivial conflict here.

> ws_object,
> )
> @@ -154,6 +158,16 @@
> self.assertEqual(1, spec_webservice.dependencies.total_size)
> self.assertEqual(spec2.name, spec_webservice.dependencies[0].name)
>
> + def test_representation_contains_bug_links(self):
> + spec = self.factory.makeSpecification()
> + bug = self.factory.makeBug()
> + person = self.factory.makePerson()
> + with person_logged_in(person):
> + spec.linkBug(bug)
> + spec_webservice = self.getSpecOnWebservice(spec)
> + self.assertEqual(1, spec_webservice.bugs.total_size)
> + self.assertEqual(bug.id, spec_webservice.bugs[0].id)
> +
>
> class SpecificationTargetTests(SpecificationWebserviceTestCase):
> """Tests for accessing specifications via their targets."""
>
> === mo...

Read more...

Revision history for this message
James Westby (james-w) wrote :

On Thu, 02 Dec 2010 12:11:14 -0000, Guilherme Salgado <email address hidden> wrote:
> I don't think we use the field you changed for constructing any forms,
> so I'd be surprised if this has any side effects.

That's good news.

> As we talked on IRC, I thought just exporting IBugLinkTarget as an entry
> would make it work, but apparently it didn't?

Nope, I had this diff minus the inheritence change and it didn't
work. I'm asking again for some advice on this on IRC.

> A trivial conflict here.

Fixed.

> I think you should use Reference instead of Object here. I don't
> remember why we have Reference (which is a wrapper around Object), but
> that's what we seem to use in conjunction with CollectionFields.

Ok.

> Also, this interface is provided only by ISpecification and IQuestion
> (which is not yet exposed on the API), so I think it makes sense to
> expose it only on the 'devel' version of the webservice, like all the
> Blueprints bits that are currently exposed. To do that you just need a
> couple extra arguments to exported:
>
> ('devel', dict(exported=True)), exported=False)

I also fixed the docstring to match the current state of the code.

Thanks,

James

Revision history for this message
Guilherme Salgado (salgado) wrote :

Looks good to me

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/blueprints/interfaces/specification.py'
2--- lib/lp/blueprints/interfaces/specification.py 2010-12-01 12:54:42 +0000
3+++ lib/lp/blueprints/interfaces/specification.py 2010-12-02 15:19:59 +0000
4@@ -58,6 +58,7 @@
5 IHasSpecifications,
6 ISpecificationTarget,
7 )
8+from lp.bugs.interfaces.buglink import IBugLinkTarget
9 from lp.blueprints.interfaces.sprint import ISprint
10 from lp.code.interfaces.branchlink import IHasLinkedBranches
11 from lp.registry.interfaces.milestone import IMilestone
12@@ -529,7 +530,8 @@
13 """Return the SpecificationBranch link for the branch, or None."""
14
15
16-class ISpecification(ISpecificationPublic, ISpecificationEditRestricted):
17+class ISpecification(ISpecificationPublic, ISpecificationEditRestricted,
18+ IBugLinkTarget):
19 """A Specification."""
20
21 export_as_webservice_entry()
22
23=== modified file 'lib/lp/blueprints/tests/test_webservice.py'
24--- lib/lp/blueprints/tests/test_webservice.py 2010-12-01 12:54:42 +0000
25+++ lib/lp/blueprints/tests/test_webservice.py 2010-12-02 15:19:59 +0000
26@@ -15,6 +15,7 @@
27 from lp.testing import (
28 launchpadlib_for,
29 launchpadlib_for_anonymous,
30+ person_logged_in,
31 TestCaseWithFactory,
32 ws_object,
33 )
34@@ -154,6 +155,16 @@
35 self.assertEqual(1, spec_webservice.dependencies.total_size)
36 self.assertEqual(spec2.name, spec_webservice.dependencies[0].name)
37
38+ def test_representation_contains_bug_links(self):
39+ spec = self.factory.makeSpecification()
40+ bug = self.factory.makeBug()
41+ person = self.factory.makePerson()
42+ with person_logged_in(person):
43+ spec.linkBug(bug)
44+ spec_webservice = self.getSpecOnWebservice(spec)
45+ self.assertEqual(1, spec_webservice.bugs.total_size)
46+ self.assertEqual(bug.id, spec_webservice.bugs[0].id)
47+
48
49 class SpecificationTargetTests(SpecificationWebserviceTestCase):
50 """Tests for accessing specifications via their targets."""
51
52=== modified file 'lib/lp/bugs/interfaces/buglink.py'
53--- lib/lp/bugs/interfaces/buglink.py 2010-08-20 20:31:18 +0000
54+++ lib/lp/bugs/interfaces/buglink.py 2010-12-02 15:19:59 +0000
55@@ -14,6 +14,14 @@
56 'IUnlinkBugsForm',
57 ]
58
59+from lazr.restful.declarations import (
60+ export_as_webservice_entry,
61+ exported,
62+ )
63+from lazr.restful.fields import (
64+ CollectionField,
65+ Reference,
66+ )
67 from zope.interface import (
68 implements,
69 Interface,
70@@ -48,13 +56,15 @@
71
72
73 class IBugLinkTarget(Interface):
74- """An entity which can be linked to a bug.
75+ """An entity which can be linked to bugs.
76
77- Examples include an IQuestion, and an ICve.
78+ Examples include an ISpecification.
79 """
80+ export_as_webservice_entry()
81
82- bugs = List(title=_("Bugs related to this object."),
83- value_type=Object(schema=IBug), readonly=True)
84+ bugs = exported(CollectionField(title=_("Bugs related to this object."),
85+ value_type=Reference(schema=IBug), readonly=True),
86+ ('devel', dict(exported=True)), exported=False)
87 bug_links = List(title=_("The links between bugs and this object."),
88 value_type=Object(schema=IBugLink), readonly=True)
89
90
91=== modified file 'lib/lp/bugs/interfaces/webservice.py'
92--- lib/lp/bugs/interfaces/webservice.py 2010-11-09 16:25:22 +0000
93+++ lib/lp/bugs/interfaces/webservice.py 2010-12-02 15:19:59 +0000
94@@ -17,6 +17,7 @@
95 'IBugActivity',
96 'IBugAttachment',
97 'IBugBranch',
98+ 'IBugLinkTarget',
99 'IBugNomination',
100 'IBugSubscription',
101 'IBugTarget',
102@@ -48,6 +49,7 @@
103 from lp.bugs.interfaces.bugactivity import IBugActivity
104 from lp.bugs.interfaces.bugattachment import IBugAttachment
105 from lp.bugs.interfaces.bugbranch import IBugBranch
106+from lp.bugs.interfaces.buglink import IBugLinkTarget
107 from lp.bugs.interfaces.malone import IMaloneApplication
108 from lp.bugs.interfaces.bugnomination import (
109 BugNominationStatusError,