~launchpad-pqm/launchpad/devel

10427.6.5 by Curtis Hovey
Fixed spelling.
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
10427.6.3 by Curtis Hovey
Do not suggest to 'create' a mailing list when one exists.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
__metaclass__ = type
5
12760.1.14 by Curtis Hovey
Added a notifcation to person/team index pages to explain the context is being merged.
6
from zope.component import getUtility
13785.7.2 by Aaron Bentley
Fix several team membership bugs.
7
from zope.security.proxy import removeSecurityProxy
12760.1.14 by Curtis Hovey
Added a notifcation to person/team index pages to explain the context is being merged.
8
14600.2.2 by Curtis Hovey
Moved webapp to lp.services.
9
from lp.services.webapp.publisher import canonical_url
14604.1.1 by Curtis Hovey
Separate test-authoring classes from test-running classes.
10
from lp.testing.layers import DatabaseFunctionalLayer
14097.1.1 by Steve Kowalik
First shot at moving all of the team gubbins from browser.person to browser.team
11
from lp.registry.browser.team import TeamOverviewMenu
14515.2.20 by Curtis Hovey
Added proper test for LimitedView access to team page.
12
from lp.registry.interfaces.person import PersonVisibility
12760.1.14 by Curtis Hovey
Added a notifcation to person/team index pages to explain the context is being merged.
13
from lp.registry.interfaces.persontransferjob import IPersonMergeJobSource
13785.7.2 by Aaron Bentley
Fix several team membership bugs.
14
from lp.registry.interfaces.teammembership import (
15
    ITeamMembershipSet,
16
    TeamMembershipStatus,
17
    )
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
18
from lp.testing import (
19
    login_person,
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
20
    person_logged_in,
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
21
    TestCaseWithFactory,
22
    )
11562.3.1 by Robert Collins
Refactor common assertions about BatchNavigators for reuse.
23
from lp.testing.matchers import IsConfiguredBatchNavigator
10427.6.3 by Curtis Hovey
Do not suggest to 'create' a mailing list when one exists.
24
from lp.testing.menu import check_menu_links
14578.4.4 by William Grant
format-imports.
25
from lp.testing.pages import (
26
    extract_text,
27
    find_tag_by_id,
28
    )
11954.4.1 by Curtis Hovey
Redirect users from the mailing list moderation view.
29
from lp.testing.views import (
30
    create_initialized_view,
31
    create_view,
32
    )
10427.6.3 by Curtis Hovey
Do not suggest to 'create' a mailing list when one exists.
33
34
35
class TestTeamMenu(TestCaseWithFactory):
36
37
    layer = DatabaseFunctionalLayer
38
39
    def setUp(self):
40
        super(TestTeamMenu, self).setUp()
41
        self.team = self.factory.makeTeam()
42
10427.6.5 by Curtis Hovey
Fixed spelling.
43
    def test_TeamOverviewMenu_check_menu_links_without_mailing(self):
10427.6.3 by Curtis Hovey
Do not suggest to 'create' a mailing list when one exists.
44
        menu = TeamOverviewMenu(self.team)
45
        # Remove moderate_mailing_list because it asserts that there is
46
        # a mailing list.
47
        no_mailinst_list_links = [
48
            link for link in menu.links if link != 'moderate_mailing_list']
49
        menu.links = no_mailinst_list_links
50
        self.assertEqual(True, check_menu_links(menu))
51
        link = menu.configure_mailing_list()
52
        self.assertEqual('Create a mailing list', link.text)
53
10427.6.5 by Curtis Hovey
Fixed spelling.
54
    def test_TeamOverviewMenu_check_menu_links_with_mailing(self):
13785.7.2 by Aaron Bentley
Fix several team membership bugs.
55
        self.factory.makeMailingList(
10427.6.3 by Curtis Hovey
Do not suggest to 'create' a mailing list when one exists.
56
            self.team, self.team.teamowner)
57
        menu = TeamOverviewMenu(self.team)
58
        self.assertEqual(True, check_menu_links(menu))
59
        link = menu.configure_mailing_list()
60
        self.assertEqual('Configure mailing list', link.text)
11538.1.2 by Robert Collins
Batch the mailing list moderation form.
61
62
63
class TestModeration(TestCaseWithFactory):
64
65
    layer = DatabaseFunctionalLayer
66
67
    def test_held_messages_is_batch_navigator(self):
68
        team = self.factory.makeTeam()
69
        self.factory.makeMailingList(team, team.teamowner)
70
        view = create_initialized_view(team, name='+mailinglist-moderate')
11562.3.1 by Robert Collins
Refactor common assertions about BatchNavigators for reuse.
71
        self.assertThat(
72
            view.held_messages,
73
            IsConfiguredBatchNavigator('message', 'messages'))
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
74
11954.4.1 by Curtis Hovey
Redirect users from the mailing list moderation view.
75
    def test_no_mailing_list_redirect(self):
76
        team = self.factory.makeTeam()
77
        login_person(team.teamowner)
78
        view = create_view(team, name='+mailinglist-moderate')
79
        response = view.request.response
80
        self.assertEqual(302, response.getStatus())
81
        self.assertEqual(canonical_url(team), response.getHeader('location'))
82
        self.assertEqual(1, len(response.notifications))
83
        self.assertEqual(
84
            '%s does not have a mailing list.' % (team.displayname),
85
            response.notifications[0].message)
86
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
87
88
class TestTeamMemberAddView(TestCaseWithFactory):
89
90
    layer = DatabaseFunctionalLayer
91
92
    def setUp(self):
93
        super(TestTeamMemberAddView, self).setUp()
11895.1.7 by Curtis Hovey
Converted bad stories to good unittests.
94
        self.team = self.factory.makeTeam(name='test-team')
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
95
        login_person(self.team.teamowner)
96
11895.1.8 by Curtis Hovey
Extracted common code to method.
97
    def getForm(self, new_member):
98
        return {
99
            'field.newmember': new_member.name,
100
            'field.actions.add': 'Add Member',
101
            }
102
11895.1.6 by Curtis Hovey
Clear new member field after adding a member. Do not permit empty teams to be added to a team.
103
    def test_add_member_success(self):
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
104
        member = self.factory.makePerson(name="a-member")
11895.1.8 by Curtis Hovey
Extracted common code to method.
105
        form = self.getForm(member)
11895.1.6 by Curtis Hovey
Clear new member field after adding a member. Do not permit empty teams to be added to a team.
106
        view = create_initialized_view(self.team, "+addmember", form=form)
11895.1.4 by Curtis Hovey
Clear the addmember field after successfully adding a member.
107
        self.assertEqual([], view.errors)
108
        notifications = view.request.response.notifications
109
        self.assertEqual(1, len(notifications))
110
        self.assertEqual(
111
            'A-member (a-member) has been added as a member of this team.',
112
            notifications[0].message)
113
        self.assertTrue(member.inTeam(self.team))
114
        self.assertEqual(
115
            None, view.widgets['newmember']._getCurrentValue())
11895.1.6 by Curtis Hovey
Clear new member field after adding a member. Do not permit empty teams to be added to a team.
116
11895.1.7 by Curtis Hovey
Converted bad stories to good unittests.
117
    def test_add_former_member_success(self):
118
        member = self.factory.makePerson(name="a-member")
119
        self.team.addMember(member, self.team.teamowner)
120
        with person_logged_in(member):
121
            member.leave(self.team)
11895.1.8 by Curtis Hovey
Extracted common code to method.
122
        form = self.getForm(member)
11895.1.7 by Curtis Hovey
Converted bad stories to good unittests.
123
        view = create_initialized_view(self.team, "+addmember", form=form)
124
        self.assertEqual([], view.errors)
125
        notifications = view.request.response.notifications
126
        self.assertEqual(1, len(notifications))
127
        self.assertEqual(
128
            'A-member (a-member) has been added as a member of this team.',
129
            notifications[0].message)
130
        self.assertTrue(member.inTeam(self.team))
131
132
    def test_add_existing_member_fail(self):
133
        member = self.factory.makePerson(name="a-member")
134
        self.team.addMember(member, self.team.teamowner)
11895.1.8 by Curtis Hovey
Extracted common code to method.
135
        form = self.getForm(member)
11895.1.7 by Curtis Hovey
Converted bad stories to good unittests.
136
        view = create_initialized_view(self.team, "+addmember", form=form)
137
        self.assertEqual(1, len(view.errors))
138
        self.assertEqual(
139
            "A-member (a-member) is already a member of Test Team.",
140
            view.errors[0])
141
11895.1.6 by Curtis Hovey
Clear new member field after adding a member. Do not permit empty teams to be added to a team.
142
    def test_add_empty_team_fail(self):
143
        empty_team = self.factory.makeTeam(owner=self.team.teamowner)
144
        self.team.teamowner.leave(empty_team)
11895.1.8 by Curtis Hovey
Extracted common code to method.
145
        form = self.getForm(empty_team)
11895.1.6 by Curtis Hovey
Clear new member field after adding a member. Do not permit empty teams to be added to a team.
146
        view = create_initialized_view(self.team, "+addmember", form=form)
147
        self.assertEqual(1, len(view.errors))
148
        self.assertEqual(
149
            "You can't add a team that doesn't have any active members.",
150
            view.errors[0])
11954.6.16 by Curtis Hovey
Added a view methods to get the vocabulary step_title for the team add member script.
151
13785.7.2 by Aaron Bentley
Fix several team membership bugs.
152
    def test_no_TeamMembershipTransitionError(self):
153
        # Attempting to add a team never triggers a
154
        # TeamMembershipTransitionError
155
        member_team = self.factory.makeTeam()
156
        self.team.addMember(member_team, self.team.teamowner)
157
        tm = getUtility(ITeamMembershipSet).getByPersonAndTeam(
158
            member_team, self.team)
159
        for status in TeamMembershipStatus.items:
160
            removeSecurityProxy(tm).status = status
161
            view = create_initialized_view(self.team, "+addmember")
162
            view.add_action.success(data={'newmember': member_team})
163
11954.6.16 by Curtis Hovey
Added a view methods to get the vocabulary step_title for the team add member script.
164
165
class TestTeamIndexView(TestCaseWithFactory):
166
167
    layer = DatabaseFunctionalLayer
168
169
    def setUp(self):
170
        super(TestTeamIndexView, self).setUp()
171
        self.team = self.factory.makeTeam(name='test-team')
172
        login_person(self.team.teamowner)
173
174
    def test_add_member_step_title(self):
175
        view = create_initialized_view(self.team, '+index')
176
        self.assertEqual('Search', view.add_member_step_title)
12760.1.14 by Curtis Hovey
Added a notifcation to person/team index pages to explain the context is being merged.
177
178
    def test_is_merge_pending(self):
179
        target_team = self.factory.makeTeam()
180
        job_source = getUtility(IPersonMergeJobSource)
181
        job_source.create(
182
            from_person=self.team, to_person=target_team,
183
            reviewer=target_team.teamowner)
184
        view = create_initialized_view(self.team, name="+index")
185
        notifications = view.request.response.notifications
186
        message = (
187
            'Test Team is queued to be be merged or deleted '
188
            'in a few minutes.')
189
        self.assertEqual(1, len(notifications))
190
        self.assertEqual(message, notifications[0].message)
14515.2.2 by Curtis Hovey
Added a draft test and change for LimitedView redaction rules.
191
14515.2.20 by Curtis Hovey
Added proper test for LimitedView access to team page.
192
    def test_user_without_launchpad_view(self):
193
        # When the user does not have launchpad.View on the context,
194
        user = self.factory.makePerson()
195
        owner = self.factory.makePerson()
196
        with person_logged_in(owner):
197
            team = self.factory.makeTeam(
198
                displayname='Waffles', owner=owner,
199
                visibility=PersonVisibility.PRIVATE)
200
            archive = self.factory.makeArchive(private=True, owner=team)
201
            archive.newSubscription(user, registrant=owner)
202
        with person_logged_in(user):
203
            view = create_initialized_view(
204
                team, name="+index",  server_url=canonical_url(team),
14515.2.22 by Curtis Hovey
Pass the principle to the view.
205
                path_info='', principal=user)
14515.2.20 by Curtis Hovey
Added proper test for LimitedView access to team page.
206
            document = find_tag_by_id(view(), 'document')
207
        self.assertIsNone(document.find(True, id='side-portlets'))
208
        self.assertIsNone(document.find(True, id='registration'))
209
        self.assertEndsWith(
210
            extract_text(document.find(True, id='maincontent')),
211
            'The information in this page is not shared with you.')