Code review comment for lp://staging/~julian-edwards/launchpad/schema-distro-parents
- schema-distro-parents
- Merge into db-devel
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Julian Edwards (julian-edwards) wrote : | # |
1 | === modified file 'lib/canonical/launchpad/security.py' |
2 | --- lib/canonical/launchpad/security.py 2011-04-15 16:23:07 +0000 |
3 | +++ lib/canonical/launchpad/security.py 2011-04-18 11:40:43 +0000 |
4 | @@ -1022,7 +1022,9 @@ |
5 | usedfor = IDistroSeriesParent |
6 | |
7 | def checkAuthenticated(self, user): |
8 | - return check_permission(self.permission, self.obj.derived_series) |
9 | + auth = EditDistroSeriesByReleaseManagerOrDistroOwnersOrAdmins( |
10 | + self.obj.derived_series) |
11 | + return auth.checkAuthenticated(user) |
12 | |
13 | |
14 | class ViewCountry(AnonymousAuthorization): |
15 | |
16 | === modified file 'lib/lp/registry/tests/test_distroseriesparent.py' |
17 | --- lib/lp/registry/tests/test_distroseriesparent.py 2011-04-15 15:51:18 +0000 |
18 | +++ lib/lp/registry/tests/test_distroseriesparent.py 2011-04-18 11:40:55 +0000 |
19 | @@ -34,10 +34,6 @@ |
20 | """Test the `DistroSeriesParent` model.""" |
21 | layer = ZopelessDatabaseLayer |
22 | |
23 | - def setUp(self): |
24 | - TestCaseWithFactory.setUp(self) |
25 | - #self.distribution = self.factory.makeDistribution(name='conftest') |
26 | - |
27 | def test_verify_interface(self): |
28 | # Test the interface for the model. |
29 | dsp = self.factory.makeDistroSeriesParent() |
30 | @@ -101,45 +97,36 @@ |
31 | |
32 | layer = DatabaseFunctionalLayer |
33 | |
34 | - def setUp(self): |
35 | - super(TestDistroSeriesParentSecurity, self).setUp() |
36 | - self.parent_series = self.factory.makeDistroSeries() |
37 | - self.derived_series = self.factory.makeDistroSeries() |
38 | - self.person = self.factory.makePerson() |
39 | - |
40 | def test_random_person_is_unauthorized(self): |
41 | - dsp_set = getUtility(IDistroSeriesParentSet) |
42 | - dsp = dsp_set.new(self.derived_series, self.parent_series, False) |
43 | - with person_logged_in(self.person): |
44 | + dsp = self.factory.makeDistroSeriesParent() |
45 | + person = self.factory.makePerson() |
46 | + with person_logged_in(person): |
47 | self.assertRaises( |
48 | Unauthorized, |
49 | - setattr, dsp, "derived_series", self.parent_series) |
50 | - |
51 | - def assertCanEdit(self): |
52 | - dsp_set = getUtility(IDistroSeriesParentSet) |
53 | - dsp = dsp_set.new( |
54 | - self.derived_series, self.parent_series, False) |
55 | - self.assertThat( |
56 | - dsp, |
57 | - MatchesStructure( |
58 | - derived_series=Equals(self.derived_series), |
59 | - parent_series=Equals(self.parent_series), |
60 | - initialized=Equals(False) |
61 | - )) |
62 | - |
63 | - def test_distro_drivers_can_edit(self): |
64 | - # Test that distro drivers can edit the data. |
65 | + setattr, dsp, "derived_series", dsp.parent_series) |
66 | + |
67 | + def assertCanEdit(self, dsp): |
68 | + dsp.initialized = False |
69 | + self.assertEquals(False, dsp.initialized) |
70 | + |
71 | + def test_distroseries_drivers_can_edit(self): |
72 | + # Test that distroseries drivers can edit the data. |
73 | + dsp = self.factory.makeDistroSeriesParent() |
74 | + person = self.factory.makePerson() |
75 | login(LAUNCHPAD_ADMIN) |
76 | - self.derived_series.distribution.driver = self.person |
77 | - with person_logged_in(self.person): |
78 | - self.assertCanEdit() |
79 | + dsp.derived_series.driver = person |
80 | + with person_logged_in(person): |
81 | + self.assertCanEdit(dsp) |
82 | |
83 | def test_admins_can_edit(self): |
84 | + dsp = self.factory.makeDistroSeriesParent() |
85 | login(LAUNCHPAD_ADMIN) |
86 | - self.assertCanEdit() |
87 | + self.assertCanEdit(dsp) |
88 | |
89 | def test_distro_owners_can_edit(self): |
90 | + dsp = self.factory.makeDistroSeriesParent() |
91 | + person = self.factory.makePerson() |
92 | login(LAUNCHPAD_ADMIN) |
93 | - self.derived_series.distribution.owner = self.person |
94 | - with person_logged_in(self.person): |
95 | - self.assertCanEdit() |
96 | + dsp.derived_series.distribution.owner = person |
97 | + with person_logged_in(person): |
98 | + self.assertCanEdit(dsp) |
Thanks for the review Henning!
On Monday 18 April 2011 11:22:26 you wrote:
> Review: Needs Fixing
> Hi Julian,
> thanks for adding this linking table. You indeed almost had me bored but I
> did find a few of my pet issues in your branch ... ;-)
>
> I'd really like to see the tests cleaned up before I approve this.
Not sure I agree with all of your comments there :-) But read on ...
> > sParent( AuthorizationBa se): Parent can be edited by the same people who can edit distroseries. """ ted(self, user): n(self. permission, derived_ series) sByReleaseManag erOrDistroOwner sOrAdmins directly or leave it
> > +class EditDistroSerie
> > + """DistroSeries
> > + the derived_
> > + permission = "launchpad.Edit"
> > + usedfor = IDistroSeriesParent
> > +
> > + def checkAuthentica
> > + return check_permissio
> > self.obj.
>
> Using check_permission in security adapters is flawed and needs to be
> stopped. Please see bug 764406 as to why. You can fix this by referencing
> EditDistroSerie
> in to be fixed when that bug is fixed. ;)
Woops, fixed :-)
> > === modified file 'lib/lp/ registry/ configure. zcml' registry/ interfaces/ distroseriespar ent.py' registry/ model/distroser iesparent. py'
> > === added file 'lib/lp/
> > === added file 'lib/lp/
>
> Yeah, this is the boring bit ... ;) Thanks for a solid implementation.
I've done it too many times now!
> > + def setUp(self): tory.setUp( self) makeDistributio n(name= 'conftest' )
> > + TestCaseWithFac
> > + #self.distribution =
> > self.factory.
>
> Oh, an unused setUp!
Bugger, forgot to remove it :-)
> > + interface( self): makeDistroSerie sParent( ) IDistroSeriesPa rent, dsp) (verified) (self): makeDistroSerie s() makeDistroSerie s() makeDistroSerie sParent( series= derived_ series, series= parent_ series, series= Equals( derived_ series) , series= Equals( parent_ series) , Equals( True) edSeries( self): makeDistroSerie s() makeDistroSerie s() makeDistroSerie sParent( sParent create the series? Just pick them
> > + def test_verify_
> > + # Test the interface for the model.
> > + dsp = self.factory.
> > + verified = verifyObject(
> > + self.assertTrue
> > +
> > + def test_properties
> > + # Test the model properties.
> > + parent_series = self.factory.
> > + derived_series = self.factory.
> > + dsp = self.factory.
> > + derived_
> > + parent_
> > + initialized=True
> > + )
> > +
> > + self.assertThat(
> > + dsp,
> > + MatchesStructure(
> > + derived_
> > + parent_
> > + initialized=
> > + ))
> > +
> > + def test_getByDeriv
> > + parent_series = self.factory.
> > + derived_series = self.factory.
> > + self.factory.
> > + derived_series, parent_series)
>
> Hm, why not let makeDistroSerie
> from the dsp object you get from the factory.
I've re-worked these tests entirely so it's actually testing *editing*
(previously it was doing nothing :/) and they are much simpler now.
> IDistroSeriesPa rentSet) .getByDerivedSe ries( l(parent_ series, results[ 0].parent_ series)
> > + results = getUtility(
> > + derived_series)
> > + self.assertEqual(1, results.count())
> > + self.assertEqua
> > +
> > + # Making a second parent should add it to the results.
>
> Uh-oh, two-stage test. I would prefer this in two tests.
I know a few people don't like this pattern, but IMHO that would be bad here
where the second part depends on the first. Splitting tests up makes our test
suite slower and that pisses me off more than multi-stage tests.
> makeDistroSerie sParent( makeDistroSerie s()) IDistroSeriesPa rentSet) .getByDerivedSe ries( tSeries( self): makeDistroSerie s() makeDistroSerie s() makeDistroSerie sParent(
> > + self.factory.
> > + derived_series, self.factory.
> > + results = getUtility(
> > + derived_series)
> > + self.assertEqual(2, results.count())
> > +
> > + def test_getByParen
> > + parent_series = self.factory.
> > + derived_series = self.factory.
> > + dsp = self.factory.
> > + derived_series, parent_series)
>
> Same comment about the factory method here.
Same reply :)
> IDistroSeriesPa rentSet) .getByParentSer ies( l(derived_ series, results[ 0].derived_ series)
> > + results = getUtility(
> > + parent_series)
> > + self.assertEqual(1, results.count())
> > + self.assertEqua
> > +
> > + # Making a second child should add it to the results.
>
> And here about splitting the test. ;-)
And .... same :)
> makeDistroSerie sParent( makeDistroSerie s(), parent_series) IDistroSeriesPa rentSet) .getByParentSer ies( sParentSecurity (TestCaseWithFa ctory): nalLayer oSeriesParentSe curity, self).setUp() makeDistroSerie s() makeDistroSerie s() makePerson( ) sParent, just like mentioned in the previous test case.
> > + self.factory.
> > + self.factory.
> > + results = getUtility(
> > + parent_series)
> > + self.assertEqual(2, results.count())
> > +
> > +
> > +class TestDistroSerie
> > +
> > + layer = DatabaseFunctio
> > +
> > + def setUp(self):
> > + super(TestDistr
> > + self.parent_series = self.factory.
> > + self.derived_series = self.factory.
> > + self.person = self.factory.
>
> In case you didn't notice, I don't think using setUp for sample data
> creation is a good idea. In this case, self.person is only used in two
> tests, why not just create them there? And the series could be created by
> makeDistroSerie
> Please remove setUp from this test case.
I was someone who disagreed with your email about this pattern as I take each
case on its own merits ;)
I've re-written the testst a bit anyway and negated the need for a setup at
all. See what you think.
> > + person_ is_unauthorized (self): IDistroSeriesPa rentSet) new(self. derived_ series, self.parent_series, logged_ in(self. person) : self): IDistroSeriesPa rentSet) series, self.parent_series, False) series= Equals( self.derived_ series) , series= Equals( self.parent_ series) , Equals( False) drivers_ can_edit( self): _ADMIN) series. distribution. driver = self.person logged_ in(self. person) : dit() can_edit( self): _ADMIN) dit() owners_ can_edit( self): _ADMIN) series. distribution. owner = self.person logged_ in(self. person) : dit() testing/ factory. py'
> > + def test_random_
> > + dsp_set = getUtility(
> > + dsp = dsp_set.
> > False) + with person_
> > + self.assertRaises(
> > + Unauthorized,
> > + setattr, dsp, "derived_series", self.parent_series)
> > +
> > + def assertCanEdit(
> > + dsp_set = getUtility(
> > + dsp = dsp_set.new(
> > + self.derived_
> > + self.assertThat(
> > + dsp,
> > + MatchesStructure(
> > + derived_
> > + parent_
> > + initialized=
> > + ))
> > +
> > + def test_distro_
> > + # Test that distro drivers can edit the data.
> > + login(LAUNCHPAD
> > + self.derived_
> > + with person_
> > + self.assertCanE
> > +
> > + def test_admins_
> > + login(LAUNCHPAD
> > + self.assertCanE
> > +
> > + def test_distro_
> > + login(LAUNCHPAD
> > + self.derived_
> > + with person_
> > + self.assertCanE
> >
> > === modified file 'lib/lp/
>
> Thanks for adding the factory to go with this new class.
My pleasure. Thanks for reviewing, let me know what you think.
Cheers
J