13100.3.11
by Ian Booth
Add stub pillaraffiliation implementation and remove ~ from lp name display |
1 |
# Copyright 2011 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
4 |
"""Tests for adapters."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
||
13616.1.1
by Ian Booth
Copy changes from previous branch |
8 |
from storm.store import Store |
9 |
from testtools.matchers import Equals |
|
10 |
from zope.component import getUtility |
|
11 |
||
13100.3.11
by Ian Booth
Add stub pillaraffiliation implementation and remove ~ from lp name display |
12 |
from lp.registry.model.pillaraffiliation import IHasAffiliation |
13616.1.1
by Ian Booth
Copy changes from previous branch |
13 |
from lp.services.worlddata.interfaces.language import ILanguageSet |
14 |
from lp.testing import ( |
|
15 |
person_logged_in, |
|
16 |
StormStatementRecorder, |
|
17 |
TestCaseWithFactory, |
|
18 |
)
|
|
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
19 |
from lp.testing.layers import ( |
20 |
DatabaseFunctionalLayer, |
|
21 |
LaunchpadFunctionalLayer, |
|
22 |
)
|
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
23 |
from lp.testing.matchers import HasQueryCount |
13100.3.11
by Ian Booth
Add stub pillaraffiliation implementation and remove ~ from lp name display |
24 |
|
25 |
||
26 |
class TestPillarAffiliation(TestCaseWithFactory): |
|
27 |
||
13643.2.1
by Ian Booth
Fix bug in badge icons and add tests |
28 |
layer = LaunchpadFunctionalLayer |
29 |
||
30 |
def test_distro_badge_icon(self): |
|
31 |
# A distro's icon is used for the badge if present.
|
|
32 |
person = self.factory.makePerson() |
|
33 |
icon = self.factory.makeLibraryFileAlias( |
|
34 |
filename='smurf.png', content_type='image/png') |
|
35 |
distro = self.factory.makeDistribution( |
|
36 |
owner=person, name='pting', icon=icon) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
37 |
[badges] = IHasAffiliation(distro).getAffiliationBadges([person]) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
38 |
self.assertEqual((icon.getURL(), "Pting", "maintainer"), badges[0]) |
13100.3.11
by Ian Booth
Add stub pillaraffiliation implementation and remove ~ from lp name display |
39 |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
40 |
def _check_affiliated_with_distro(self, person, distro, role): |
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
41 |
[badges] = IHasAffiliation(distro).getAffiliationBadges([person]) |
42 |
self.assertEqual( |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
43 |
("/@@/distribution-badge", "Pting", role), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
44 |
|
45 |
def test_distro_owner_affiliation(self): |
|
46 |
# A person who owns a distro is affiliated.
|
|
47 |
person = self.factory.makePerson() |
|
48 |
distro = self.factory.makeDistribution(owner=person, name='pting') |
|
49 |
self._check_affiliated_with_distro(person, distro, 'maintainer') |
|
50 |
||
51 |
def test_distro_driver_affiliation(self): |
|
52 |
# A person who is a distro driver is affiliated.
|
|
53 |
person = self.factory.makePerson() |
|
54 |
distro = self.factory.makeDistribution(driver=person, name='pting') |
|
55 |
self._check_affiliated_with_distro(person, distro, 'driver') |
|
56 |
||
57 |
def test_distro_team_driver_affiliation(self): |
|
58 |
# A person who is a member of the distro driver team is affiliated.
|
|
59 |
person = self.factory.makePerson() |
|
60 |
team = self.factory.makeTeam(members=[person]) |
|
61 |
distro = self.factory.makeDistribution(driver=team, name='pting') |
|
62 |
self._check_affiliated_with_distro(person, distro, 'driver') |
|
63 |
||
64 |
def test_no_distro_security_contact_affiliation(self): |
|
65 |
# A person who is the security contact for a distro is not affiliated
|
|
66 |
# for simple distro affiliation checks.
|
|
67 |
person = self.factory.makePerson() |
|
68 |
distro = self.factory.makeDistribution(security_contact=person) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
69 |
self.assertEqual( |
70 |
[], IHasAffiliation(distro).getAffiliationBadges([person])[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
71 |
|
72 |
def test_no_distro_bug_supervisor_affiliation(self): |
|
73 |
# A person who is the bug supervisor for a distro is not affiliated
|
|
74 |
# for simple distro affiliation checks.
|
|
75 |
person = self.factory.makePerson() |
|
76 |
distro = self.factory.makeDistribution(bug_supervisor=person) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
77 |
self.assertEqual( |
78 |
[], IHasAffiliation(distro).getAffiliationBadges([person])[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
79 |
|
13643.2.1
by Ian Booth
Fix bug in badge icons and add tests |
80 |
def test_product_badge_icon(self): |
81 |
# A product's icon is used for the badge if present.
|
|
82 |
person = self.factory.makePerson() |
|
83 |
icon = self.factory.makeLibraryFileAlias( |
|
84 |
filename='smurf.png', content_type='image/png') |
|
85 |
product = self.factory.makeProduct( |
|
86 |
owner=person, name='pting', icon=icon) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
87 |
[badges] = IHasAffiliation(product).getAffiliationBadges([person]) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
88 |
self.assertEqual((icon.getURL(), "Pting", "maintainer"), badges[0]) |
13643.2.1
by Ian Booth
Fix bug in badge icons and add tests |
89 |
|
90 |
def test_pillar_badge_icon(self): |
|
91 |
# A pillar's icon is used for the badge if the context has no icon.
|
|
92 |
person = self.factory.makePerson() |
|
93 |
icon = self.factory.makeLibraryFileAlias( |
|
94 |
filename='smurf.png', content_type='image/png') |
|
95 |
product = self.factory.makeProduct( |
|
96 |
owner=person, name='pting', icon=icon) |
|
97 |
bugtask = self.factory.makeBugTask(target=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
98 |
[badges] = IHasAffiliation(bugtask).getAffiliationBadges([person]) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
99 |
self.assertEqual((icon.getURL(), "Pting", "maintainer"), badges[0]) |
13643.2.1
by Ian Booth
Fix bug in badge icons and add tests |
100 |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
101 |
def _check_affiliated_with_product(self, person, product, role): |
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
102 |
[badges] = IHasAffiliation(product).getAffiliationBadges([person]) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
103 |
self.assertEqual(("/@@/product-badge", "Pting", role), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
104 |
|
105 |
def test_product_driver_affiliation(self): |
|
106 |
# A person who is the driver for a product is affiliated.
|
|
107 |
person = self.factory.makePerson() |
|
108 |
product = self.factory.makeProduct(driver=person, name='pting') |
|
109 |
self._check_affiliated_with_product(person, product, 'driver') |
|
110 |
||
111 |
def test_product_team_driver_affiliation(self): |
|
112 |
# A person who is a member of the product driver team is affiliated.
|
|
113 |
person = self.factory.makePerson() |
|
114 |
team = self.factory.makeTeam(members=[person]) |
|
115 |
product = self.factory.makeProduct(driver=team, name='pting') |
|
116 |
self._check_affiliated_with_product(person, product, 'driver') |
|
117 |
||
118 |
def test_product_group_driver_affiliation(self): |
|
119 |
# A person who is the driver for a product's group is affiliated.
|
|
120 |
person = self.factory.makePerson() |
|
121 |
project = self.factory.makeProject(driver=person) |
|
122 |
product = self.factory.makeProduct(project=project, name='pting') |
|
123 |
self._check_affiliated_with_product(person, product, 'driver') |
|
124 |
||
125 |
def test_no_product_security_contact_affiliation(self): |
|
126 |
# A person who is the security contact for a product is is not
|
|
127 |
# affiliated for simple product affiliation checks.
|
|
128 |
person = self.factory.makePerson() |
|
129 |
product = self.factory.makeProduct(security_contact=person) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
130 |
self.assertEqual( |
131 |
[], IHasAffiliation(product).getAffiliationBadges([person])[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
132 |
|
133 |
def test_no_product_bug_supervisor_affiliation(self): |
|
134 |
# A person who is the bug supervisor for a product is is not
|
|
135 |
# affiliated for simple product affiliation checks.
|
|
136 |
person = self.factory.makePerson() |
|
137 |
product = self.factory.makeProduct(bug_supervisor=person) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
138 |
self.assertEqual( |
139 |
[], IHasAffiliation(product).getAffiliationBadges([person])[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
140 |
|
141 |
def test_product_owner_affiliation(self): |
|
142 |
# A person who owns a product is affiliated.
|
|
143 |
person = self.factory.makePerson() |
|
144 |
product = self.factory.makeProduct(owner=person, name='pting') |
|
145 |
self._check_affiliated_with_product(person, product, 'maintainer') |
|
146 |
||
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
147 |
def test_distro_affiliation_multiple_people(self): |
148 |
# A collection of people associated with a distro are affiliated.
|
|
149 |
people = [self.factory.makePerson() for x in range(3)] |
|
150 |
distro = self.factory.makeDistribution(owner=people[0], |
|
151 |
driver=people[1], |
|
152 |
name='pting') |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
153 |
person_badges = IHasAffiliation(distro).getAffiliationBadges(people) |
154 |
self.assertEqual( |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
155 |
[("/@@/distribution-badge", "Pting", "maintainer")], |
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
156 |
person_badges[0]) |
157 |
self.assertEqual( |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
158 |
[("/@@/distribution-badge", "Pting", "driver")], person_badges[1]) |
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
159 |
self.assertEqual([], person_badges[2]) |
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
160 |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
161 |
def test_product_affiliation_query_count(self): |
162 |
# Only 2 queries are expected, selects from:
|
|
163 |
# - Product, Person
|
|
164 |
person = self.factory.makePerson() |
|
165 |
product = self.factory.makeProduct(owner=person, name='pting') |
|
166 |
Store.of(product).invalidate() |
|
167 |
with StormStatementRecorder() as recorder: |
|
168 |
IHasAffiliation(product).getAffiliationBadges([person]) |
|
169 |
self.assertThat(recorder, HasQueryCount(Equals(2))) |
|
170 |
||
171 |
def test_distro_affiliation_query_count(self): |
|
172 |
# Only 2 business queries are expected, selects from:
|
|
173 |
# - Distribution, Person
|
|
174 |
# plus an additional query to create a PublisherConfig record.
|
|
175 |
person = self.factory.makePerson() |
|
176 |
distro = self.factory.makeDistribution(owner=person, name='pting') |
|
177 |
Store.of(distro).invalidate() |
|
178 |
with StormStatementRecorder() as recorder: |
|
179 |
IHasAffiliation(distro).getAffiliationBadges([person]) |
|
180 |
self.assertThat(recorder, HasQueryCount(Equals(3))) |
|
181 |
||
13616.1.1
by Ian Booth
Copy changes from previous branch |
182 |
|
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
183 |
class _TestBugTaskorBranchMixin: |
13616.1.1
by Ian Booth
Copy changes from previous branch |
184 |
|
185 |
def test_distro_security_contact_affiliation(self): |
|
186 |
# A person who is the security contact for a distro is affiliated.
|
|
187 |
person = self.factory.makePerson() |
|
188 |
distro = self.factory.makeDistribution( |
|
189 |
security_contact=person, name='pting') |
|
190 |
self._check_affiliated_with_distro(person, distro, 'security contact') |
|
191 |
||
192 |
def test_distro_bug_supervisor_affiliation(self): |
|
193 |
# A person who is the bug supervisor for a distro is affiliated.
|
|
194 |
person = self.factory.makePerson() |
|
195 |
distro = self.factory.makeDistribution( |
|
196 |
bug_supervisor=person, name='pting') |
|
197 |
self._check_affiliated_with_distro(person, distro, 'bug supervisor') |
|
198 |
||
199 |
def test_product_security_contact_affiliation(self): |
|
200 |
# A person who is the security contact for a distro is affiliated.
|
|
201 |
person = self.factory.makePerson() |
|
202 |
product = self.factory.makeProduct( |
|
203 |
security_contact=person, name='pting') |
|
204 |
self._check_affiliated_with_product( |
|
205 |
person, product, 'security contact') |
|
206 |
||
207 |
def test_product_bug_supervisor_affiliation(self): |
|
208 |
# A person who is the bug supervisor for a distro is affiliated.
|
|
209 |
person = self.factory.makePerson() |
|
210 |
product = self.factory.makeProduct( |
|
211 |
bug_supervisor=person, name='pting') |
|
212 |
self._check_affiliated_with_product(person, product, 'bug supervisor') |
|
213 |
||
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
214 |
|
215 |
class TestBugTaskPillarAffiliation(_TestBugTaskorBranchMixin, |
|
216 |
TestCaseWithFactory): |
|
217 |
||
218 |
layer = DatabaseFunctionalLayer |
|
219 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
220 |
def test_correct_pillars_are_used(self): |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
221 |
bugtask = self.factory.makeBugTask() |
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
222 |
adapter = IHasAffiliation(bugtask) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
223 |
pillars = [bugtask.pillar for bugtask in bugtask.bug.bugtasks] |
224 |
self.assertEqual(pillars, adapter.getPillars()) |
|
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
225 |
|
226 |
def _check_affiliated_with_distro(self, person, target, role): |
|
227 |
bugtask = self.factory.makeBugTask(target=target) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
228 |
[badges] = IHasAffiliation(bugtask).getAffiliationBadges([person]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
229 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
230 |
("/@@/distribution-badge", "Pting", role), badges[0]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
231 |
|
232 |
def _check_affiliated_with_product(self, person, target, role): |
|
233 |
bugtask = self.factory.makeBugTask(target=target) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
234 |
[badges] = IHasAffiliation(bugtask).getAffiliationBadges([person]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
235 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
236 |
("/@@/product-badge", "Pting", role), badges[0]) |
237 |
||
238 |
def test_affiliated_with_multiple_bugtasks(self): |
|
239 |
# When a bugtask belongs to a bug which has other bugtasks, all such
|
|
240 |
# bugtasks are checked for affiliation.
|
|
241 |
person = self.factory.makePerson() |
|
242 |
bug = self.factory.makeBug() |
|
243 |
expected_affiliations = [] |
|
244 |
for x in range(3): |
|
245 |
bug_supervisor = None |
|
246 |
if x == 0: |
|
247 |
bug_supervisor = person |
|
248 |
product = self.factory.makeProduct( |
|
249 |
owner=person, bug_supervisor=bug_supervisor) |
|
250 |
self.factory.makeBugTask(bug=bug, target=product) |
|
251 |
expected_affiliations.append( |
|
252 |
("/@@/product-badge", product.displayname, "maintainer")) |
|
253 |
expected_affiliations.append( |
|
254 |
("/@@/product-badge", product.displayname, "driver")) |
|
255 |
if x == 0: |
|
256 |
expected_affiliations.append( |
|
257 |
("/@@/product-badge", |
|
258 |
product.displayname, "bug supervisor")) |
|
259 |
[badges] = IHasAffiliation( |
|
260 |
bug.default_bugtask).getAffiliationBadges([person]) |
|
261 |
self.assertContentEqual(expected_affiliations, badges) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
262 |
|
263 |
||
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
264 |
class TestBranchPillarAffiliation(_TestBugTaskorBranchMixin, |
265 |
TestCaseWithFactory): |
|
266 |
||
267 |
layer = DatabaseFunctionalLayer |
|
268 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
269 |
def test_correct_pillars_are_used(self): |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
270 |
branch = self.factory.makeBranch() |
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
271 |
adapter = IHasAffiliation(branch) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
272 |
self.assertEqual([branch.product], adapter.getPillars()) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
273 |
|
14033.3.1
by Curtis Hovey
Personal branches do not have project affiliation. |
274 |
def test_personal_branches_have_no_pillars(self): |
275 |
branch = self.factory.makeBranch(product=None) |
|
276 |
adapter = IHasAffiliation(branch) |
|
277 |
self.assertEqual([], adapter.getPillars()) |
|
278 |
||
13721.1.4
by Curtis Hovey
Cleaned up doctrings and hushed lint. |
279 |
def test_getBranch(self): |
280 |
# The branch is the context.
|
|
281 |
branch = self.factory.makeBranch() |
|
282 |
adapter = IHasAffiliation(branch) |
|
283 |
self.assertEqual(branch, adapter.getBranch()) |
|
284 |
||
285 |
def test_branch_trusted_reviewer_affiliation(self): |
|
286 |
# A person who is the branch's trusted reviewer is affiliated.
|
|
287 |
person = self.factory.makePerson() |
|
288 |
product = self.factory.makeProduct(name='pting') |
|
289 |
self._check_affiliated_with_product( |
|
290 |
person, product, 'trusted reviewer') |
|
291 |
||
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
292 |
def _check_affiliated_with_distro(self, person, target, role): |
293 |
distroseries = self.factory.makeDistroSeries(distribution=target) |
|
294 |
sp = self.factory.makeSourcePackage(distroseries=distroseries) |
|
295 |
branch = self.factory.makeBranch(sourcepackage=sp) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
296 |
[badges] = IHasAffiliation(branch).getAffiliationBadges([person]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
297 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
298 |
("/@@/distribution-badge", "Pting", role), badges[0]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
299 |
|
300 |
def _check_affiliated_with_product(self, person, target, role): |
|
301 |
branch = self.factory.makeBranch(product=target) |
|
13721.1.2
by Curtis Hovey
Include the branch's trusted reviewer among the affiliated users. |
302 |
with person_logged_in(branch.owner): |
303 |
branch.reviewer = person |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
304 |
[badges] = IHasAffiliation(branch).getAffiliationBadges([person]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
305 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
306 |
("/@@/product-badge", "Pting", role), badges[0]) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
307 |
|
13721.1.4
by Curtis Hovey
Cleaned up doctrings and hushed lint. |
308 |
|
309 |
class CodeReviewVotePillarAffiliationTestCase(TestBranchPillarAffiliation): |
|
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
310 |
|
311 |
layer = DatabaseFunctionalLayer |
|
312 |
||
313 |
def makeCodeReviewVote(self, branch): |
|
314 |
merge_proposal = self.factory.makeBranchMergeProposal( |
|
315 |
target_branch=branch) |
|
316 |
reviewer = self.factory.makePerson() |
|
317 |
with person_logged_in(merge_proposal.registrant): |
|
318 |
vote = merge_proposal.nominateReviewer( |
|
319 |
reviewer, merge_proposal.registrant) |
|
320 |
return vote |
|
321 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
322 |
def test_correct_pillars_are_used(self): |
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
323 |
branch = self.factory.makeBranch() |
324 |
vote = self.makeCodeReviewVote(branch) |
|
325 |
adapter = IHasAffiliation(vote) |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
326 |
self.assertEqual([branch.product], adapter.getPillars()) |
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
327 |
|
13721.1.4
by Curtis Hovey
Cleaned up doctrings and hushed lint. |
328 |
def test_getBranch(self): |
329 |
# The code review vote's target branch is the branch.
|
|
330 |
branch = self.factory.makeBranch() |
|
331 |
vote = self.makeCodeReviewVote(branch) |
|
332 |
adapter = IHasAffiliation(vote) |
|
333 |
self.assertEqual(branch, adapter.getBranch()) |
|
334 |
||
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
335 |
def _check_affiliated_with_distro(self, person, target, role): |
336 |
distroseries = self.factory.makeDistroSeries(distribution=target) |
|
337 |
sp = self.factory.makeSourcePackage(distroseries=distroseries) |
|
338 |
branch = self.factory.makeBranch(sourcepackage=sp) |
|
339 |
vote = self.makeCodeReviewVote(branch) |
|
340 |
[badges] = IHasAffiliation(vote).getAffiliationBadges([person]) |
|
341 |
self.assertEqual( |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
342 |
("/@@/distribution-badge", "Pting", role), badges[0]) |
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
343 |
|
344 |
def _check_affiliated_with_product(self, person, target, role): |
|
345 |
branch = self.factory.makeBranch(product=target) |
|
346 |
with person_logged_in(branch.owner): |
|
347 |
branch.reviewer = person |
|
13721.1.4
by Curtis Hovey
Cleaned up doctrings and hushed lint. |
348 |
vote = self.makeCodeReviewVote(branch) |
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
349 |
[badges] = IHasAffiliation(vote).getAffiliationBadges([person]) |
350 |
self.assertEqual( |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
351 |
("/@@/product-badge", "Pting", role), badges[0]) |
13721.1.3
by Curtis Hovey
Added CodeReviewVotePillarAffiliation. |
352 |
|
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
353 |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
354 |
class TestDistroSeriesPillarAffiliation(TestCaseWithFactory): |
355 |
||
356 |
layer = DatabaseFunctionalLayer |
|
357 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
358 |
def test_correct_pillars_are_used(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
359 |
series = self.factory.makeDistroSeries() |
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
360 |
adapter = IHasAffiliation(series) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
361 |
self.assertEqual([series.distribution], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
362 |
|
363 |
def test_driver_affiliation(self): |
|
364 |
# A person who is the driver for a distroseries is affiliated.
|
|
365 |
# Here, the affiliation is with the distribution of the series.
|
|
366 |
owner = self.factory.makePerson() |
|
367 |
driver = self.factory.makePerson() |
|
368 |
distribution = self.factory.makeDistribution( |
|
369 |
owner=owner, driver=driver, name='pting') |
|
370 |
distroseries = self.factory.makeDistroSeries( |
|
371 |
registrant=driver, distribution=distribution) |
|
13721.1.4
by Curtis Hovey
Cleaned up doctrings and hushed lint. |
372 |
[badges] = IHasAffiliation( |
373 |
distroseries).getAffiliationBadges([driver]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
374 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
375 |
("/@@/distribution-badge", "Pting", "driver"), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
376 |
|
377 |
def test_distro_driver_affiliation(self): |
|
378 |
# A person who is the driver for a distroseries' distro is affiliated.
|
|
379 |
# Here, the affiliation is with the distribution of the series.
|
|
380 |
owner = self.factory.makePerson() |
|
381 |
driver = self.factory.makePerson() |
|
382 |
distribution = self.factory.makeDistribution( |
|
383 |
owner=owner, driver=driver, name='pting') |
|
384 |
distroseries = self.factory.makeDistroSeries( |
|
385 |
registrant=owner, distribution=distribution) |
|
13721.1.4
by Curtis Hovey
Cleaned up doctrings and hushed lint. |
386 |
[badges] = IHasAffiliation( |
387 |
distroseries).getAffiliationBadges([driver]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
388 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
389 |
("/@@/distribution-badge", "Pting", "driver"), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
390 |
|
391 |
||
392 |
class TestProductSeriesPillarAffiliation(TestCaseWithFactory): |
|
393 |
||
394 |
layer = DatabaseFunctionalLayer |
|
395 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
396 |
def test_correct_pillars_are_used(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
397 |
series = self.factory.makeProductSeries() |
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
398 |
adapter = IHasAffiliation(series) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
399 |
self.assertEqual([series.product], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
400 |
|
401 |
def test_driver_affiliation(self): |
|
402 |
# A person who is the driver for a productseries is affiliated.
|
|
403 |
# Here, the affiliation is with the product.
|
|
404 |
owner = self.factory.makePerson() |
|
405 |
driver = self.factory.makePerson() |
|
406 |
product = self.factory.makeProduct( |
|
407 |
owner=owner, driver=driver, name='pting') |
|
408 |
productseries = self.factory.makeProductSeries( |
|
409 |
owner=driver, product=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
410 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
411 |
IHasAffiliation(productseries).getAffiliationBadges([driver])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
412 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
413 |
("/@@/product-badge", "Pting", "driver"), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
414 |
|
415 |
def test_product_driver_affiliation(self): |
|
416 |
# A person who is the driver for a productseries' product is
|
|
417 |
# affiliated. Here, the affiliation is with the product.
|
|
418 |
owner = self.factory.makePerson() |
|
419 |
driver = self.factory.makePerson() |
|
420 |
product = self.factory.makeProduct( |
|
421 |
owner=owner, driver=driver, name='pting') |
|
422 |
productseries = self.factory.makeProductSeries( |
|
423 |
owner=owner, product=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
424 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
425 |
IHasAffiliation(productseries).getAffiliationBadges([driver])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
426 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
427 |
("/@@/product-badge", "Pting", "driver"), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
428 |
|
429 |
def test_product_group_driver_affiliation(self): |
|
430 |
# A person who is the driver for a productseries' product's group is
|
|
431 |
# affiliated. Here, the affiliation is with the product.
|
|
432 |
owner = self.factory.makePerson() |
|
433 |
driver = self.factory.makePerson() |
|
434 |
project = self.factory.makeProject(driver=driver) |
|
435 |
product = self.factory.makeProduct( |
|
436 |
owner=owner, project=project, name='pting') |
|
437 |
productseries = self.factory.makeProductSeries( |
|
438 |
owner=owner, product=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
439 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
440 |
IHasAffiliation(productseries).getAffiliationBadges([driver])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
441 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
442 |
("/@@/product-badge", "Pting", "driver"), badges[0]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
443 |
|
444 |
||
445 |
class TestQuestionPillarAffiliation(TestCaseWithFactory): |
|
446 |
||
447 |
layer = DatabaseFunctionalLayer |
|
448 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
449 |
def test_correct_pillars_are_used_for_product(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
450 |
product = self.factory.makeProduct() |
451 |
question = self.factory.makeQuestion(target=product) |
|
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
452 |
adapter = IHasAffiliation(question) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
453 |
self.assertEqual([question.product], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
454 |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
455 |
def test_correct_pillars_are_used_for_distribution(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
456 |
distribution = self.factory.makeDistribution() |
457 |
question = self.factory.makeQuestion(target=distribution) |
|
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
458 |
adapter = IHasAffiliation(question) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
459 |
self.assertEqual([question.distribution], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
460 |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
461 |
def test_correct_pillars_are_used_for_distro_sourcepackage(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
462 |
distribution = self.factory.makeDistribution() |
463 |
distro_sourcepackage = self.factory.makeDistributionSourcePackage( |
|
464 |
distribution=distribution) |
|
465 |
owner = self.factory.makePerson() |
|
466 |
question = self.factory.makeQuestion( |
|
467 |
target=distro_sourcepackage, owner=owner) |
|
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
468 |
adapter = IHasAffiliation(question) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
469 |
self.assertEqual([distribution], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
470 |
|
471 |
def test_answer_contact_affiliation_for_distro(self): |
|
472 |
# A person is affiliated if they are an answer contact for a distro
|
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
473 |
# target.
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
474 |
answer_contact = self.factory.makePerson() |
475 |
english = getUtility(ILanguageSet)['en'] |
|
476 |
answer_contact.addLanguage(english) |
|
477 |
distro = self.factory.makeDistribution(owner=answer_contact) |
|
478 |
with person_logged_in(answer_contact): |
|
479 |
distro.addAnswerContact(answer_contact, answer_contact) |
|
480 |
question = self.factory.makeQuestion(target=distro) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
481 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
482 |
IHasAffiliation(question).getAffiliationBadges([answer_contact])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
483 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
484 |
("/@@/distribution-badge", distro.displayname, |
485 |
"maintainer"), badges[0]) |
|
486 |
self.assertEqual( |
|
487 |
("/@@/distribution-badge", distro.displayname, |
|
488 |
"driver"), badges[1]) |
|
489 |
self.assertEqual( |
|
490 |
("/@@/distribution-badge", distro.displayname, |
|
491 |
"answer contact"), badges[2]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
492 |
|
493 |
def test_answer_contact_affiliation_for_distro_sourcepackage(self): |
|
494 |
# A person is affiliated if they are an answer contact for a dsp
|
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
495 |
# target.
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
496 |
answer_contact = self.factory.makePerson() |
497 |
english = getUtility(ILanguageSet)['en'] |
|
498 |
answer_contact.addLanguage(english) |
|
499 |
distribution = self.factory.makeDistribution(owner=answer_contact) |
|
500 |
distro_sourcepackage = self.factory.makeDistributionSourcePackage( |
|
501 |
distribution=distribution) |
|
502 |
with person_logged_in(answer_contact): |
|
503 |
distro_sourcepackage.addAnswerContact( |
|
504 |
answer_contact, answer_contact) |
|
505 |
question = self.factory.makeQuestion( |
|
506 |
target=distro_sourcepackage, owner=answer_contact) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
507 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
508 |
IHasAffiliation(question).getAffiliationBadges([answer_contact])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
509 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
510 |
("/@@/distribution-badge", distribution.displayname, |
511 |
"maintainer"), badges[0]) |
|
512 |
self.assertEqual( |
|
513 |
("/@@/distribution-badge", distribution.displayname, |
|
514 |
"driver"), badges[1]) |
|
515 |
self.assertEqual( |
|
516 |
("/@@/distribution-badge", distro_sourcepackage.displayname, |
|
517 |
"answer contact"), badges[2]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
518 |
|
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
519 |
def test_answer_contact_affiliation_for_distro_sourcepackage_distro(self): |
520 |
# A person is affiliated if they are an answer contact for a dsp
|
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
521 |
# target's distro.
|
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
522 |
answer_contact = self.factory.makePerson() |
523 |
english = getUtility(ILanguageSet)['en'] |
|
524 |
answer_contact.addLanguage(english) |
|
525 |
distribution = self.factory.makeDistribution(owner=answer_contact) |
|
526 |
distro_sourcepackage = self.factory.makeDistributionSourcePackage( |
|
527 |
distribution=distribution) |
|
528 |
with person_logged_in(answer_contact): |
|
529 |
distribution.addAnswerContact(answer_contact, answer_contact) |
|
530 |
question = self.factory.makeQuestion( |
|
531 |
target=distro_sourcepackage, owner=answer_contact) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
532 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
533 |
IHasAffiliation(question).getAffiliationBadges([answer_contact])) |
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
534 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
535 |
("/@@/distribution-badge", distribution.displayname, |
536 |
"maintainer"), badges[0]) |
|
537 |
self.assertEqual( |
|
538 |
("/@@/distribution-badge", distribution.displayname, |
|
539 |
"driver"), badges[1]) |
|
540 |
self.assertEqual( |
|
541 |
("/@@/distribution-badge", distribution.displayname, |
|
542 |
"answer contact"), badges[2]) |
|
13616.1.2
by Ian Booth
Make question affiliation code more efficient and add Branch affiliation adapter |
543 |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
544 |
def test_answer_contact_affiliation_for_product(self): |
545 |
# A person is affiliated if they are an answer contact for a product
|
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
546 |
# target.
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
547 |
answer_contact = self.factory.makePerson() |
548 |
english = getUtility(ILanguageSet)['en'] |
|
549 |
answer_contact.addLanguage(english) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
550 |
product = self.factory.makeProduct() |
13616.1.1
by Ian Booth
Copy changes from previous branch |
551 |
with person_logged_in(answer_contact): |
552 |
product.addAnswerContact(answer_contact, answer_contact) |
|
553 |
question = self.factory.makeQuestion(target=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
554 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
555 |
IHasAffiliation(question).getAffiliationBadges([answer_contact])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
556 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
557 |
("/@@/product-badge", product.displayname, "answer contact"), |
558 |
badges[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
559 |
|
560 |
def test_product_affiliation(self): |
|
561 |
# A person is affiliated if they are affiliated with the product.
|
|
562 |
person = self.factory.makePerson() |
|
563 |
product = self.factory.makeProduct(owner=person) |
|
564 |
question = self.factory.makeQuestion(target=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
565 |
[badges] = IHasAffiliation(question).getAffiliationBadges([person]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
566 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
567 |
("/@@/product-badge", product.displayname, "maintainer"), |
568 |
badges[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
569 |
|
570 |
def test_distribution_affiliation(self): |
|
571 |
# A person is affiliated if they are affiliated with the distribution.
|
|
572 |
person = self.factory.makePerson() |
|
573 |
distro = self.factory.makeDistribution(owner=person) |
|
574 |
question = self.factory.makeQuestion(target=distro) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
575 |
[badges] = IHasAffiliation(question).getAffiliationBadges([person]) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
576 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
577 |
("/@@/distribution-badge", distro.displayname, "maintainer"), |
578 |
badges[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
579 |
|
580 |
||
581 |
class TestSpecificationPillarAffiliation(TestCaseWithFactory): |
|
582 |
||
583 |
layer = DatabaseFunctionalLayer |
|
584 |
||
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
585 |
def test_correct_pillars_are_used_for_product(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
586 |
product = self.factory.makeProduct() |
587 |
specification = self.factory.makeSpecification(product=product) |
|
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
588 |
adapter = IHasAffiliation(specification) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
589 |
self.assertEqual([specification.product], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
590 |
|
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
591 |
def test_correct_pillars_are_used_for_distribution(self): |
13616.1.1
by Ian Booth
Copy changes from previous branch |
592 |
distro = self.factory.makeDistribution() |
593 |
specification = self.factory.makeSpecification(distribution=distro) |
|
13616.1.4
by Ian Booth
Refactor vocab items processing to use set based interfaces for generating picker entries |
594 |
adapter = IHasAffiliation(specification) |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
595 |
self.assertEqual([specification.distribution], adapter.getPillars()) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
596 |
|
597 |
def test_product_affiliation(self): |
|
598 |
# A person is affiliated if they are affiliated with the pillar.
|
|
599 |
person = self.factory.makePerson() |
|
600 |
product = self.factory.makeProduct(owner=person) |
|
601 |
specification = self.factory.makeSpecification(product=product) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
602 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
603 |
IHasAffiliation(specification).getAffiliationBadges([person])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
604 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
605 |
("/@@/product-badge", product.displayname, "maintainer"), |
606 |
badges[0]) |
|
13616.1.1
by Ian Booth
Copy changes from previous branch |
607 |
|
608 |
def test_distribution_affiliation(self): |
|
609 |
# A person is affiliated if they are affiliated with the distribution.
|
|
610 |
person = self.factory.makePerson() |
|
611 |
distro = self.factory.makeDistribution(owner=person) |
|
612 |
specification = self.factory.makeSpecification(distribution=distro) |
|
13646.5.2
by Ian Booth
Initial refactor to support multiple badges |
613 |
[badges] = ( |
13616.1.7
by Ian Booth
Fix some style issues |
614 |
IHasAffiliation(specification).getAffiliationBadges([person])) |
13616.1.1
by Ian Booth
Copy changes from previous branch |
615 |
self.assertEqual( |
13850.1.1
by Ian Booth
Change how badge info is packaged to allow more than one affiliation to be displayed |
616 |
("/@@/distribution-badge", distro.displayname, "maintainer"), |
617 |
badges[0]) |