Merge lp:~jtv/launchpad/bug-567035 into lp:launchpad

Proposed by Jeroen T. Vermeulen on 2010-04-20
Status: Merged
Approved by: Gavin Panella on 2010-04-21
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~jtv/launchpad/bug-567035
Merge into: lp:launchpad
Diff against target: 92 lines (+67/-3)
2 files modified
lib/lp/translations/model/translationgroup.py (+2/-3)
lib/lp/translations/tests/test_translationgroup.py (+65/-0)
To merge this branch: bzr merge lp:~jtv/launchpad/bug-567035
Reviewer Review Type Date Requested Status
Gavin Panella (community) 2010-04-20 Approve on 2010-04-21
Review via email: mp+23742@code.launchpad.net

Commit Message

Fix duplicate translation groups on Language page.

Description of the Change

= Bug 567035 =

Tiny fix: where the Language page lists experts and the translation groups they participate in, the groups lists contained duplicates, caused by redundant indirect memberships (and possibly multi-language translation teams). This fixes that.

No lint. To test:
{{{
./bin/test -vv -t getByPerson_distinct
}}}

For Q/A, go https://translations.edge.launchpad.net/+languages/es (or equivalent for staging) and verify that under Translation Teams, Rocrail and Jisko Translators do not have their names repeated more than once between parentheses.

Jeroen

To post a comment you must log in.
Gavin Panella (allenap) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/translations/model/translationgroup.py'
2--- lib/lp/translations/model/translationgroup.py 2010-02-22 09:06:38 +0000
3+++ lib/lp/translations/model/translationgroup.py 2010-04-20 05:32:17 +0000
4@@ -180,8 +180,7 @@
5 owner=owner)
6
7 def getByPerson(self, person):
8- """See ITranslationGroupSet."""
9-
10+ """See `ITranslationGroupSet`."""
11 store = Store.of(person)
12 origin = [
13 TranslationGroup,
14@@ -193,7 +192,7 @@
15 result = store.using(*origin).find(
16 TranslationGroup, TeamParticipation.person == person)
17
18- return result.order_by(TranslationGroup.title)
19+ return result.config(distinct=True).order_by(TranslationGroup.title)
20
21 def getGroupsCount(self):
22 """See ITranslationGroupSet."""
23
24=== added file 'lib/lp/translations/tests/test_translationgroup.py'
25--- lib/lp/translations/tests/test_translationgroup.py 1970-01-01 00:00:00 +0000
26+++ lib/lp/translations/tests/test_translationgroup.py 2010-04-20 05:32:17 +0000
27@@ -0,0 +1,65 @@
28+# Copyright 2010 Canonical Ltd. This software is licensed under the
29+# GNU Affero General Public License version 3 (see the file LICENSE).
30+
31+"""Unit tests for `TranslationGroup` and related classes."""
32+
33+__metaclass__ = type
34+
35+from unittest import TestLoader
36+
37+from zope.component import getUtility
38+
39+from canonical.testing import ZopelessDatabaseLayer
40+from lp.registry.interfaces.teammembership import (
41+ ITeamMembershipSet, TeamMembershipStatus)
42+from lp.testing import TestCaseWithFactory
43+from lp.translations.interfaces.translationgroup import ITranslationGroupSet
44+
45+
46+class TestTranslationGroupSet(TestCaseWithFactory):
47+ layer = ZopelessDatabaseLayer
48+
49+ def _enrollInTeam(self, team, member):
50+ """Make `member` a member of `team`."""
51+ getUtility(ITeamMembershipSet).new(
52+ member, team, TeamMembershipStatus.APPROVED, team.teamowner)
53+
54+ def _makeTranslationTeam(self, group, member, language_code):
55+ """Create translation team and enroll `member` in it."""
56+ team = self.factory.makeTeam()
57+ self.factory.makeTranslator(language_code, group=group, person=team)
58+ self._enrollInTeam(team, member)
59+ return team
60+
61+ def test_getByPerson_distinct_membership(self):
62+ # A person can be in a translation team multiple times through
63+ # indirect membership, but a group using that team will show up
64+ # only once in getByPerson.
65+ group = self.factory.makeTranslationGroup()
66+ person = self.factory.makePerson()
67+ translation_team = self._makeTranslationTeam(group, person, 'nl')
68+
69+ nested_team = self.factory.makeTeam()
70+ self._enrollInTeam(translation_team, nested_team)
71+ self._enrollInTeam(nested_team, person)
72+
73+ self.assertEqual(
74+ [group],
75+ list(getUtility(ITranslationGroupSet).getByPerson(person)))
76+
77+ def test_getByPerson_distinct_translationteam(self):
78+ # getByPerson returns a group only once even if the person is a
79+ # member of multiple translation teams in the group.
80+ group = self.factory.makeTranslationGroup()
81+ person = self.factory.makePerson()
82+
83+ self._makeTranslationTeam(group, person, 'es')
84+ self._makeTranslationTeam(group, person, 'ca')
85+
86+ self.assertEqual(
87+ [group],
88+ list(getUtility(ITranslationGroupSet).getByPerson(person)))
89+
90+
91+def test_suite():
92+ return TestLoader().loadTestsFromName(__name__)