~adeuring/launchpad/api-export-bug-linked-branches

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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
= PPA Subscription Stories =

The owner or admin of a private PPA can add subscribers - people
or teams - to the private archive. This will enable subscribers to obtain
a custom sources.list entry and access the repository.

The owner or admin of a private archive can also edit or cancel
subscribers related to the archive.

== Setup Helpers ==

Just so the definition of these helpers doesn't get in the way of the
story text, define them here.

First create a helper function for printing the archive subscriptions
of a person:

    >>> def print_subscriptions_for_person(contents):
    ...     subscriptions = find_tags_by_class(contents,
    ...                                        'archive-subscription-row')
    ...     for subscription in subscriptions:
    ...         print extract_text(subscription)

== Story: An archive owner can add a subscription for a private archive ==

 * As a software developer who plans to release some private software
 * I want to add certain users or teams as subscribers of my PPA
 * So that they can download my software.

=== Scenario 1: A user is added as a subscriber ===

Given a private PPA for Celso,

    >>> from zope.component import getUtility
    >>> from lp.registry.interfaces.person import IPersonSet
    >>> login('admin@canonical.com')
    >>> cprov = getUtility(IPersonSet).getByName('cprov')
    >>> from lp.registry.interfaces.distribution import IDistributionSet
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
    >>> private_ppa = factory.makeArchive(
    ...     owner=cprov, name="p3a", distribution=ubuntu, private=True)
    >>> logout()

and a browser for Celso currently navigated to the Manage Subscriptions page,

    >>> cprov_browser = setupBrowser(
    ...     auth="Basic celso.providelo@canonical.com:cprov")
    >>> cprov_browser.open(
    ...     "http://launchpad.dev/~cprov/+archive/p3a/+subscriptions")

and a client of Celso's who has a launchpad name of 'joesmith'

    >>> login('foo.bar@canonical.com')
    >>> client = factory.makePerson(name="joesmith", displayname="Joe Smith",
    ...     password="test", email="joe@example.com")
    >>> logout()

When Celso fills in the form with 'joesmith' as the subscriber, a blank
subscription expiry, a description of "Joe is my friend" and clicks on the
"Add subscriber" button,

    >>> cprov_browser.getControl(name='field.subscriber').value = 'joesmith'
    >>> cprov_browser.getControl(
    ...     name='field.description').value = "Joe is my friend"
    >>> cprov_browser.getControl(name="field.actions.add").click()

then he is redirected to the subscribers page and the new subscription
is displayed with a notification about the new subscriber.

Create a helper function to print subscriptions:
    >>> def print_archive_subscriptions(contents):
    ...     subscriptions = find_tags_by_class(contents,
    ...                                        'archive_subscriber_row')
    ...     for subscription in subscriptions:
    ...         print extract_text(subscription)

    >>> print_archive_subscriptions(cprov_browser.contents)
    Name                Expires     Comment
    Joe Smith                       Joe is my friend    Edit/Cancel

    >>> for msg in get_feedback_messages(cprov_browser.contents):
    ...     print msg
    You have granted access for Joe Smith to install software from
    PPA named p3a for Celso Providelo. Joe Smith will be notified of the
    access via email.


=== Scenario 2: A team is added as a subscriber ===

Given a private PPA for Celso and a browser for Celso currently navigated
to the Manage Subscriptions page, when Celso fills in the form with the
'launchpad' team as the subscriber, an expiry date of '2200-08-01',
a description of "Launchpad developer access." and clicks on the
"Add subscriber" button,

    >>> cprov_browser.open(
    ...     "http://launchpad.dev/~cprov/+archive/p3a/+subscriptions")
    >>> cprov_browser.getControl(name='field.subscriber').value = 'launchpad'
    >>> cprov_browser.getControl(
    ...     name='field.date_expires').value = '2200-08-01'
    >>> cprov_browser.getControl(
    ...     name='field.description').value = "Launchpad developer access."
    >>> cprov_browser.getControl(name="field.actions.add").click()

then Celso is redirected to the subscribers page, the new subscription
for the launchpad team is displayed as well as a notification about the
new subscriber.

    >>> print_archive_subscriptions(cprov_browser.contents)
    Name                    Expires       Comment
    Launchpad Developers    2200-08-01    Launchpad developer access.
    ...

    >>> for msg in get_feedback_messages(cprov_browser.contents):
    ...     print msg
    You have granted access for Launchpad Developers to install software
    from PPA named p3a for Celso Providelo. Members of Launchpad Developers
    will be notified of the access via email.

== Story 2: An owner edits a subscription for his private archive ==

 * As a software developer who has released some private software
 * I want to edit subscriptions to my private PPA
 * So that I can adjust who can download my software.

=== Scenario 1: Adjusting the details of a subscription ===

Given a private PPA for Celso, a subscription to Celso's private PPA
for the Launchpad Developers team and a browser for Celso currently
navigated to the Manage Subscriptions page,

    >>> cprov_browser.open(
    ...     "http://launchpad.dev/~cprov/+archive/p3a/+subscriptions")

when Celso clicks 'Edit/Cancel' for the Launchpad Developers subscription,
modifies the description field and clicks Update,

    >>> cprov_browser.getLink(
    ...     url='/~cprov/+archive/p3a/+subscriptions/launchpad/+edit').click()
    >>> cprov_browser.getControl(name="field.description").value = (
    ...     "a different description")
    >>> cprov_browser.getControl(name="field.actions.update").click()

then the browser is redirected back to the subscriptions page, the updated subscription for the launchpad team is displayed as well as a notification
about the update.

    >>> print cprov_browser.url
    http://launchpad.dev/~cprov/+archive/p3a/+subscriptions
    >>> print_archive_subscriptions(cprov_browser.contents)
    Name                    Expires       Comment
    Launchpad Developers    2200-08-01    a different description
    ...
    >>> for msg in get_feedback_messages(cprov_browser.contents):
    ...     print msg
    The access for Launchpad Developers has been updated.

=== Scenario 2: Canceling a subscription ===

Given a private PPA for Celso, a subscription to Celso's private PPA for
the Launchpad Developers team and a browser for Celso currently navigated
to the Manage Subscriptions page,

    >>> cprov_browser.open(
    ...     "http://launchpad.dev/~cprov/+archive/p3a/+subscriptions")

when Celso clicks 'Edit/Cancel' for the Launchpad Developers subscription
and clicks Cancel,

    >>> cprov_browser.getLink(
    ...     url='/~cprov/+archive/p3a/+subscriptions/launchpad/+edit').click()
    >>> cprov_browser.getControl(name="field.actions.cancel").click()

then the browser is redirected back to the subscriptions page, the canceled
subscription is no longer displayed and a notification about the
cancellation is displayed.

    >>> print cprov_browser.url
    http://launchpad.dev/~cprov/+archive/p3a/+subscriptions
    >>> print_archive_subscriptions(cprov_browser.contents)
    Name                    Expires       Comment
    Joe Smith                             Joe is my friend    Edit/Cancel

    >>> for msg in get_feedback_messages(cprov_browser.contents):
    ...     print msg
    You have revoked Launchpad Developers's access to PPA
    named p3a for Celso Providelo.


== Story 3: A subscriber activates a subscription ==

 * As a user of Celso's software,
 * I want to obtain a private sources.list entry
 * So that I can download and get updates for the software in
   Celso's private PPA.

=== Scenario 1: A user activates a personal subscription ===

Given a subscription for Celso's private PPA for Joe Smith, when
Joe visits his profile and clicks 'View your private PPA subscriptions'
then he'll see a list of his current subscriptions.

    >>> joe_browser = setupBrowser(auth="Basic joe@example.com:test")
    >>> joe_browser.open("http://launchpad.dev/~joesmith")
    >>> joe_browser.getLink('View your private PPA subscriptions').click()
    >>> print_subscriptions_for_person(joe_browser.contents)
    Archive        Owner
    PPA named ...  Celso Providelo  View

When Joe clicks on the View button for Celso's PPA then the
details of the subscription are displayed with the newly created
access details.

    >>> joe_browser.getControl(name="activate").click()
    >>> sources_list = find_tag_by_id(joe_browser.contents, 'sources_list')
    >>> print(extract_text(sources_list))
    Custom sources.list entries
    ...
    deb http://joesmith:...@private-ppa.launchpad.dev/cprov/p3a/ubuntu
        hoary main #Personal access of Joe Smith
        to PPA named p3a for Celso Providelo
    deb-src http://joesmith:...@private-ppa.launchpad.dev/cprov/p3a/ubuntu
        hoary main #Personal access of Joe Smith
        to PPA named p3a for Celso Providelo

When Joe navigates back to his current archive subscriptions then the list of
subscriptions reflects the confirmed subscription, providing a normal
link to view the details.

    >>> joe_browser.open(
    ...     "http://launchpad.dev/~joesmith/+archivesubscriptions")
    >>> print_subscriptions_for_person(joe_browser.contents)
    Archive        Owner
    PPA named ...  Celso Providelo  View

    >>> joe_browser.getLink('View').click()
    >>> print(extract_text(joe_browser.contents))
    Access to PPA named p3a for Celso Providelo...

=== Scenario 2: A user re-generates the token for a subscription ===

Given an activated subscription to Celso's private PPA, when Joe visits
his private archive subscriptions page and clicks on the 'view' link to view
a subscription then information regarding the generation of a new personal
subscription is displayed.

    >>> joe_browser.open(
    ...     "http://launchpad.dev/~joesmith/+archivesubscriptions")
    >>> joe_browser.getLink('View').click()
    >>> regeneration_info = find_tag_by_id(
    ...     joe_browser.contents, 'regenerate_token')
    >>> print(extract_text(regeneration_info))
    Reset password
    If you believe...
    Note: after ...

When Joe clicks on the 'Generate new personal subscription' link then
the page is redisplayed with new sources.list entries and a notification.

    >>> joe_browser.getControl(name='regenerate_btn').click()
    >>> for msg in get_feedback_messages(joe_browser.contents):
    ...     print msg
    Launchpad has generated the new password you requested for your
    access to the archive PPA named p3a for Celso Providelo. Please
    follow the instructions below to update your custom "sources.list".


=== Scenario 3: A user activates a team subscription ===

Given a subscription for Celso's private PPA for the Launchpad Team and
a user Mark who is a member of the Launchpad team,

    >>> login('celso.providelo@canonical.com')
    >>> from zope.component import getUtility
    >>> from lp.registry.interfaces.person import IPersonSet
    >>> cprov = getUtility(IPersonSet).getByName('cprov')
    >>> launchpad = getUtility(IPersonSet).getByName('launchpad')
    >>> ignore = private_ppa.newSubscription(launchpad, cprov)
    >>> logout()
    >>> login('foo.bar@canonical.com')
    >>> foobar = getUtility(IPersonSet).getByName('name16')
    >>> mark = getUtility(IPersonSet).getByName('mark')
    >>> ignored = launchpad.addMember(mark, foobar)
    >>> import transaction
    >>> transaction.commit()
    >>> logout()

When Mark, a member of the Launchpad team, visits his profile and clicks
'View your private PPA subscriptions', then he'll see a list of his current
subscriptions.

    >>> mark_browser = setupBrowser(auth='Basic mark@example.com:test')
    >>> mark_browser.open(
    ...     "http://launchpad.dev/~mark")

    >>> mark_browser.getLink('View your private PPA subscriptions').click()
    >>> print_subscriptions_for_person(mark_browser.contents)
    Archive        Owner
    PPA named ...  Celso Providelo  View

When Mark clicks on the view button, then he is taken to the page for
his personal subscription for Celso's private PPA and the newly-created
access details are displayed.

    >>> mark_browser.getControl(name="activate").click()
    >>> sources_list = find_tag_by_id(mark_browser.contents, 'sources_list')
    >>> print(extract_text(sources_list))
    Custom sources.list entries
    ...
    deb http://mark:...@private-ppa.launchpad.dev/cprov/p3a/ubuntu
        hoary main #Personal access of
        Mark Shuttleworth to PPA named p3a for Celso Providelo
    deb-src http://mark:...@private-ppa.launchpad.dev/cprov/p3a/ubuntu
        hoary main #Personal access of
        Mark Shuttleworth to PPA named p3a for Celso Providelo

When Mark navigates back to his current archive subscriptions then the list of
subscriptions reflects the confirmed subscription, providing a normal
link to view the details.

    >>> mark_browser.open(
    ...     "http://launchpad.dev/~mark/+archivesubscriptions")
    >>> print_subscriptions_for_person(mark_browser.contents)
    Archive        Owner
    PPA named ...  Celso Providelo  View

    >>> mark_browser.getLink('View').click()
    >>> print(extract_text(mark_browser.contents))
    Access to PPA named p3a for Celso Providelo...


== Story 4: A user's subscription expires or is cancelled ==

 * As a user of Celso's software
 * I want to know (eventually, be notified) when my subscription expires
 * So that I understand why I can no longer download Celso's software

=== Scenario 1: Accessing details for an expired subscription ===

Given an expired subscription for Celso's private PPA

When Andrew visits his subscriptions
Then the page clearly identifies the subscription as no longer valid
And there is no entry in the sources.list for the expired subscription.

=== Scenario 2: Accessing details for a cancelled subscription ===

Given a cancelled subscription for Celso's private PPA

When Andrew visits his subscriptions
Then the page clearly identifies the subscription as no longer valid
And there is no entry in the sources.list for the expired subscription.