tests.py 11.6 KB
Newer Older
1 2
from datetime import datetime, timedelta

3
from django.conf import settings
4
from django.core import mail
5
from django.test import TestCase
6
from django.urls import reverse
7 8
from django.utils.translation import ugettext_lazy

9 10
from people.models import Person
from teams.models import Team, Role
11
from languages.models import Language
12 13


14
class TeamsAndRolesTests(TestCase):
15 16 17
    def setUp(self):
        self.pn = Person(first_name='John', last_name='Nothing',
            email='jn@devnull.com', username= 'jn')
18
        self.pn.set_password('password')
19 20
        self.pn.save()

21
        self.pt = Person.objects.create(first_name='John', last_name='Translator',
22 23
            email='jt@tf1.com', username= 'jt')

24
        self.pr = Person.objects.create(first_name='John', last_name='Reviewer',
25 26
            email='jr@csa.com', username= 'jr')

27
        self.pc = Person.objects.create(first_name='John', last_name='Committer',
28 29
            email='jc@alinsudesonpleingre.fr', username= 'jc',
            last_login=datetime.now()-timedelta(days=30*6-1)) #active person, but in limit date
30 31 32

        self.pcoo = Person(first_name='John', last_name='Coordinator',
            email='jcoo@imthebigboss.fr', username= 'jcoo')
33
        self.pcoo.set_password('password')
34 35
        self.pcoo.save()

36 37
        self.t = Team.objects.create(name='fr', description='French',
            mailing_list='french_ml@example.org')
38

39
        self.t2 = Team.objects.create(name='pt', description='Portuguese')
40

41
        self.l = Language.objects.create(name='French', locale='fr', team=self.t)
42

43 44 45 46 47 48 49
        Role.objects.bulk_create([
            Role(team=self.t, person=self.pt),
            Role(team=self.t2, person=self.pt, role='reviewer'),
            Role(team=self.t, person=self.pr, role='reviewer'),
            Role(team=self.t, person=self.pc, role='committer'),
            Role(team=self.t, person=self.pcoo, role='coordinator'),
        ])
50

51 52
class TeamTest(TeamsAndRolesTests):
    def setUp(self):
Claude Paroz's avatar
Claude Paroz committed
53
        super().setUp()
54 55 56 57 58 59

    def test_get_members_by_role_exact(self):
        members = self.t.get_members_by_role_exact('committer')
        t = Team.objects.get(name='fr')
        self.assertEqual(len(members), 1)
        self.assertEqual(members[0], self.pc)
60

61 62 63
        role = Role.objects.get(person=self.pc, team=t)
        role.is_active = False
        role.save()
64

65 66
        members = self.t.get_members_by_role_exact('committer')
        self.assertEqual(len(members), 0)
67

68 69 70 71 72 73 74 75
    def test_get_inactive_members(self):
        members = self.t.get_inactive_members()
        self.assertEqual(len(members), 0)

        t = Team.objects.get(name='fr')
        role = Role.objects.get(person=self.pc, team=t)
        role.is_active = False
        role.save()
76

77 78 79
        members = self.t.get_inactive_members()
        self.assertEqual(len(members), 1)
        self.assertEqual(members[0], self.pc)
80

81
    def run_roles_exact_test(self, team):
82 83
        pcoords = team.get_coordinators()
        self.assertEqual(pcoords[0], self.pcoo)
84 85

        members = team.get_committers_exact()
86
        self.assertEqual(len(members), 1)
87 88 89
        self.assertEqual(members[0], self.pc)

        members = team.get_reviewers_exact()
90
        self.assertEqual(len(members), 1)
91 92 93
        self.assertEqual(members[0], self.pr)

        members = team.get_translators_exact()
94
        self.assertEqual(len(members), 1)
95 96 97 98 99 100 101 102 103 104 105 106
        self.assertEqual(members[0], self.pt)

    def test_roles_exact(self):
        self.run_roles_exact_test(self.t)

    def test_roles_exact_prefilled_coordinator(self):
        self.run_roles_exact_test(Team.objects.all_with_coordinator()[0])

    def test_roles_exact_prefilled_all(self):
        self.run_roles_exact_test(Team.objects.all_with_roles()[0])

    def run_roles_test(self, team):
107 108 109
        """
        Tests the hierarchy of roles
        """
110 111 112
        members = team.get_committers()
        self.assertEqual(len(members), 2)
        for pc in members:
113
            self.assertTrue(pc in [self.pcoo, self.pc])
114

115 116 117
        members = team.get_reviewers()
        self.assertEqual(len(members), 3)
        for pc in members:
118
            self.assertTrue(pc in [self.pcoo, self.pc, self.pr])
119 120 121 122

        members = team.get_translators()
        self.assertEqual(len(members), 4)
        for pc in members:
123
            self.assertTrue(pc in [self.pcoo, self.pc, self.pr, self.pt])
124 125 126 127 128 129

    def test_roles(self):
        self.run_roles_test(self.t)

    def test_roles_prefilled_coordinator(self):
        self.run_roles_test(Team.objects.all_with_coordinator()[0])
130

131 132
    def test_roles_prefilled_all(self):
        self.run_roles_test(Team.objects.all_with_roles()[0])
133 134

    def test_join_team(self):
135 136
        response = self.client.post('/login/',
            {'username': self.pn.username, 'password': 'password'})
137 138
        # Display team join page
        team_join_url = reverse('person_team_join', current_app='people')
139
        response = self.client.get(team_join_url)
Claude Paroz's avatar
Claude Paroz committed
140
        self.assertContains(response, "<select ")
141
        # Post for joining
142
        response = self.client.post(team_join_url, {'teams':[str(self.t.pk)]})
143 144 145
        # Test user is member of team
        self.assertTrue(self.pn.is_translator(self.t))
        # Test coordinator receives email
146 147
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].recipients()[0], self.pcoo.email)
148
        # Mail should be sent in the target team's language (i.e. French here)
149
        self.assertIn("rejoindre", mail.outbox[0].body)
150

Claude Paroz's avatar
Claude Paroz committed
151 152 153 154 155 156 157 158
    def test_leave_team(self):
        Role.objects.create(team=self.t, person=self.pn, role='translator')
        self.client.login(username='jn', password='password')
        response = self.client.post(reverse('person_team_leave', args=[self.t.name]))
        self.assertRedirects(response, reverse('person_detail_username', args=[self.pn.username]))
        self.pn.refresh_from_db()
        self.assertEqual(self.pn.role_set.count(), 0)

159 160 161
    def test_edit_team(self):
        """ Test team edit form """
        edit_url = reverse('team_edit', args = ['fr'], current_app='teams')
162 163
        response = self.client.get(edit_url)
        self.assertEqual(response.status_code, 403)
164
        # Login as team coordinator
165 166
        response = self.client.post('/login/',
            {'username': self.pcoo.username, 'password': 'password'})
167
        # Try team modification
168 169 170 171
        response = self.client.post(edit_url, {
            'webpage_url'  : "http://www.gnomefr.org/",
            'mailing_list' : "gnomefr@traduc.org",
            'mailing_list_subscribe': ""
172 173
        })
        team = Team.objects.get(name='fr')
174
        self.assertEqual(team.webpage_url, "http://www.gnomefr.org/")
175

176 177 178
    def test_edit_team_roles(self):
        team_url = reverse('team_slug', args = ['fr'])
        # Login as team coordinator
Claude Paroz's avatar
Claude Paroz committed
179
        self.client.post('/login/',
180 181
            {'username': self.pcoo.username, 'password': 'password'})
        # Team member role modification
Claude Paroz's avatar
Claude Paroz committed
182
        self.client.post(team_url, {
183 184 185 186 187 188
            'form_type': 'reviewer',
            '%d' % Role.objects.get(team=self.t, person=self.pr).pk: 'committer',
        })
        self.assertEqual(len(mail.outbox), 1)
        self.assertIn('Role changed', mail.outbox[0].subject)
        self.assertIn(
189
            "Your role in the French team on %s has been set to “Committer”" % settings.SITE_DOMAIN,
190 191 192 193
            mail.outbox[0].body
        )
        mail.outbox = []
        # Team member removal
Claude Paroz's avatar
Claude Paroz committed
194
        self.client.post(team_url, {
195 196 197 198 199 200
            'form_type': 'translator',
            '%d' % Role.objects.get(team=self.t, person=self.pt).pk: 'remove',
        })
        self.assertEqual(len(mail.outbox), 1)
        self.assertIn('Removed from team', mail.outbox[0].subject)
        self.assertIn(
201
            "You have been removed from the French team on %s" % settings.SITE_DOMAIN,
202 203 204
            mail.outbox[0].body
        )

205 206 207
    def test_send_mail_to_coordinator(self):
        self.t.send_mail_to_coordinator(subject="foo", message="bar")
        self.assertEqual(len(mail.outbox), 1)
208 209
        self.assertEqual(mail.outbox[0].subject, "%s foo" % settings.EMAIL_SUBJECT_PREFIX)
        self.assertEqual(mail.outbox[0].extra_headers, {settings.EMAIL_HEADER_NAME: 'coordinator-mail'})
210 211 212
        # the message is sent in the language of the team
        self.t.send_mail_to_coordinator(subject=ugettext_lazy("About Damned Lies"), message="...")
        self.assertEqual(len(mail.outbox), 2)
213 214 215 216
        self.assertEqual(
            mail.outbox[1].subject,
            "%s À propos de Damned Lies" % settings.EMAIL_SUBJECT_PREFIX
        )
217 218


219 220
class JSONTeamsTest(TeamsAndRolesTests):
    def setUp(self):
Claude Paroz's avatar
Claude Paroz committed
221
        super().setUp()
222 223 224 225 226 227 228 229 230 231
        t3 = Team.objects.create(name='gl', description='Galician')
        coor1 = Person.objects.create(first_name='Marcos', last_name='Coordinator',
            email='marc@imthebigboss.fr', username='marcos', svn_account='thesvnaccount')
        coor2 = Person.objects.create(first_name='Pepe', last_name='Coordinator',
            email='pepe@imthebigboss.es', username='pepe')
        Role.objects.create(team=t3, person=coor1, role='coordinator')
        Role.objects.create(team=t3, person=coor2, role='coordinator')

    def test_json_teams(self):
        """Test JSON teams interface"""
232
        response = self.client.get(reverse('teams', args=['json']))
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
        self.assertEqual(response.status_code, 200)
        expected_JSON = """[
            {
                "id":"fr",
                "description":"French",
                "coordinators": [
                {
                    "name":"John Coordinator"
                }]
            },
            {
                "id":"gl",
                "description":"Galician",
                "coordinators": [
                    {
                        "name":"Marcos Coordinator",
                        "vcs":"thesvnaccount"
                    },
                    {
                        "name":"Pepe Coordinator"
                    }
                ]
            },
            {
                "id":"pt",
                "description":"Portuguese",
                "coordinators": []
            }
            ]"""
262
        self.assertJSONEqual(response.content.decode('utf-8'), expected_JSON)
263

264 265 266 267

class RoleTest(TeamsAndRolesTests):

    def setUp(self):
Claude Paroz's avatar
Claude Paroz committed
268
        super().setUp()
269 270 271 272

        self.pt.last_login = datetime.now()-timedelta(days=10) # active person
        self.pt.save()

273
        self.pr.last_login = datetime.now()-timedelta(days=30*6+1) # inactive person
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
        self.pr.save()

        self.pc.last_login = datetime.now()-timedelta(days=30*6-1) #active person, but in limit date
        self.pc.save()

        self.role = Role.objects.get(team=self.t, person=self.pt)
        self.role2 = Role.objects.get(team=self.t2, person=self.pt)
        self.role_inactive = Role.objects.get(team=self.t, person=self.pr)
        self.role_limit_date = Role.objects.get(team=self.t, person=self.pc)

    def test_inactivating_roles(self):
        # Testing if is_active is True by default
        self.assertTrue(self.role.is_active)
        self.assertTrue(self.role2.is_active)
        self.assertTrue(self.role_limit_date.is_active)
289
        self.assertTrue(self.role_inactive.is_active)
290 291 292 293 294 295 296 297 298 299 300

        Role.inactivate_unused_roles()

        # Getting roles from database after update the unused roles
        self.role = Role.objects.get(team=self.t, person=self.pt)
        self.role2 = Role.objects.get(team=self.t2, person=self.pt)
        self.role_inactive = Role.objects.get(team=self.t, person=self.pr)
        self.role_limit_date = Role.objects.get(team=self.t, person=self.pc)

        self.assertTrue(self.role.is_active)
        self.assertTrue(self.role2.is_active)
301
        self.assertTrue(self.role_limit_date.is_active)
302
        self.assertFalse(self.role_inactive.is_active)