~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Test Archive features."""

from zope.security.interfaces import Unauthorized

from canonical.launchpad.testing.pages import (
    find_tag_by_id,
    setupBrowserForUser,
    )
from canonical.launchpad.webapp.publisher import canonical_url
from canonical.testing.layers import DatabaseFunctionalLayer
from lp.registry.interfaces.person import PersonVisibility
from lp.testing import (
    BrowserTestCase,
    celebrity_logged_in,
    login_person,
    person_logged_in,
    TestCaseWithFactory,
    )
from lp.testing.mail_helpers import pop_notifications
from lp.testing.views import create_initialized_view


class TestArchiveSubscriptions(TestCaseWithFactory):
    """Edge-case tests for private PPA subscribers.

    See also lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt
    """

    layer = DatabaseFunctionalLayer

    def setUp(self):
        """Create a test archive."""
        super(TestArchiveSubscriptions, self).setUp()
        self.owner = self.factory.makePerson()
        self.private_team = self.factory.makeTeam(
            visibility=PersonVisibility.PRIVATE,
            name="subscribertest", owner=self.owner)
        login_person(self.owner)
        self.archive = self.factory.makeArchive(
            private=True, owner=self.private_team)
        self.subscriber = self.factory.makePerson()

    def test_subscriber_can_access_private_team_ppa(self):
        # As per bug 597783, we need to make sure a subscriber can see
        # a private team's PPA after they have been given a subscription.
        # This is essentially allowing access for the subscriber to see
        # the private team.
        def get_name():
            return self.archive.owner.name

        # Before a subscription, accessing the team name will raise.
        login_person(self.subscriber)
        self.assertRaises(Unauthorized, get_name)

        login_person(self.owner)
        self.archive.newSubscription(
            self.subscriber, registrant=self.archive.owner)

        # When a subscription exists, it's fine.
        login_person(self.subscriber)
        self.assertEqual(self.archive.owner.name, "subscribertest")

    def test_subscriber_can_browse_private_team_ppa(self):
        # As per bug 597783, we need to make sure a subscriber can see
        # a private team's PPA after they have been given a subscription.
        # This test ensures the subscriber can correctly load the PPA's view,
        # thus ensuring that all attributes necessary to render the view have
        # the necessary security permissions.

        # Before a subscription, accessing the view name will raise.
        login_person(self.subscriber)
        view = create_initialized_view(
            self.archive, '+index', principal=self.subscriber)
        self.assertRaises(Unauthorized, view.render)

        login_person(self.owner)
        self.archive.newSubscription(
            self.subscriber, registrant=self.archive.owner)

        # When a subscription exists, it's fine.
        login_person(self.subscriber)
        self.assertIn(self.archive.displayname, view.render())

        # Just to double check, by default, the subscriber still can't see the
        # +packages view which requires extra permissions.
        self.assertRaises(
            Unauthorized, create_initialized_view,
            self.archive, '+packages', principal=self.subscriber)

    def test_new_subscription_sends_email(self):
        # Creating a new subscription sends an email to all members
        # of the person or team subscribed.
        self.assertEqual(0, len(pop_notifications()))

        self.archive.newSubscription(
            self.subscriber, registrant=self.archive.owner)

        notifications = pop_notifications()
        self.assertEqual(1, len(notifications))
        self.assertEqual(
            self.subscriber.preferredemail.email,
            notifications[0]['to'])

    def test_new_commercial_subscription_no_email(self):
        # As per bug 611568, an email is not sent for commercial PPAs.
        with celebrity_logged_in('commercial_admin'):
            self.archive.commercial = True

        # Logging in as a celebrity team causes an email to be sent
        # because a person is added as a member of the team, so this
        # needs to be cleared out before calling newSubscription().
        pop_notifications()

        self.archive.newSubscription(
            self.subscriber, registrant=self.archive.owner)

        self.assertEqual(0, len(pop_notifications()))


class PrivateArtifactsViewTestCase(BrowserTestCase):
    """ Tests that private team archives can be viewed."""

    layer = DatabaseFunctionalLayer

    def setUp(self):
        """Create a test archive."""
        super(PrivateArtifactsViewTestCase, self).setUp()
        self.owner = self.factory.makePerson()
        self.private_team = self.factory.makeTeam(
            visibility=PersonVisibility.PRIVATE,
            name="subscribertest", owner=self.owner)
        with person_logged_in(self.owner):
            self.archive = self.factory.makeArchive(
                private=True, owner=self.private_team)
        self.subscriber = self.factory.makePerson()

    def test_traverse_view_private_team_archive_subscriber(self):
        # A subscriber can traverse and view the archive.
        with person_logged_in(self.owner):
            self.archive.newSubscription(
                self.subscriber, registrant=self.archive.owner)
        with person_logged_in(self.subscriber):
            url = canonical_url(self.archive)
        browser = setupBrowserForUser(self.subscriber)
        browser.open(url)
        content = find_tag_by_id(browser.contents, 'document')
        self.assertIsNotNone(find_tag_by_id(content, 'ppa-install'))
        self.assertIsNotNone(
            find_tag_by_id(content, 'portlet-latest-updates'))